rails-erb-loader: Error: rails-erb-loader failed with code: 1

Running the following: ruby -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) /Users/swathishah/shopify-app/bin/spring rails --trace assets:precompile

But I randomly get following error:

ERROR in ./app/javascript/components/layout_tab.js.erb
Module build failed: Error: rails-erb-loader failed with code: 1
    at ChildProcess.<anonymous> (/Users/swathishah/shopify-app/node_modules/rails-erb-loader/index.js:108:16)
    at emitTwo (events.js:106:13)
    at ChildProcess.emit (events.js:191:7)
    at maybeClose (internal/child_process.js:886:16)
    at Socket.<anonymous> (internal/child_process.js:342:11)
    at emitOne (events.js:96:13)
    at Socket.emit (events.js:188:7)
    at Pipe._handle.close [as _onclose] (net.js:501:12)
 @ ./app/javascript/components/tabs.js 12:0-44
 @ ./app/javascript/packs/notifications_react.jsx

Package.json has following:

{
  "name": "shopify-app",
  "private": true,
  "dependencies": {
    "@rails/webpacker": "^3.2.1",
....
   "rails-erb-loader": "^5.4.1",
...
    "yarn": "^1.3.2"
  },
  "devDependencies": {
    "webpack-dev-server": "^2.11.1"
}

About this issue

  • Original URL
  • State: open
  • Created 6 years ago
  • Reactions: 9
  • Comments: 81 (1 by maintainers)

Commits related to this issue

Most upvoted comments

We had a similar problem with erb-loader on CircleCI. Everything worked fine locally but failed to build on CircleCi.

I sshed into CI job and ran

$ cat app/javascript/vendor/javascripts/smart_listing/smart_listing.coffee.erb | bin/rails runner ./node_modules/rails-erb-loader/erb_transformer.rb __RAILS_ERB_LOADER_DELIMETER__ erb

for my .erb file. But it was giving me an error that rake was not found. It was an issue with spring. Disabling spring for the job worked.

So in our case it was DISABLE_SPRING=1 bin/webpack

Link to the spring issue. https://github.com/rails/spring/pull/546

I’ve come across this error as well. In my case, the Rails Runner script was invoked with the global Ruby installation, not my local rbenv version. bin/rails has the default shebang (#!/usr/bin/env ruby), which works in my default shell, but obviously not with spawn?

The error message I got was

12% building modules 22/25 modules 3 active $RAILS_ROOT/app/javascript/i18n.js.erb
Ignoring bcrypt-3.1.12 because its extensions are not built.  Try: gem pristine bcrypt --version 3.1.12
Ignoring bcrypt_pbkdf-1.0.0 because its extensions are not built.  Try: gem pristine bcrypt_pbkdf --version 1.0.0
Ignoring binding_of_caller-0.8.0 because its extensions are not built.  Try: gem pristine binding_of_caller --version 0.8.0
 $RBENV_GEMSET_DIR/gems/bundler-1.16.2/lib/bundler/spec_set.rb:91:in `block in materialize': Could not find nokogiri-1.8.2 in any of the sources (Bundler::GemNotFound)
	from $RBENV_GEMSET_DIR/gems/bundler-1.16.2/lib/bundler/spec_set.rb:85:in `map!'
	from $RBENV_GEMSET_DIR/gems/bundler-1.16.2/lib/bundler/spec_set.rb:85:in `materialize'
	from $RBENV_GEMSET_DIR/gems/bundler-1.16.2/lib/bundler/definition.rb:171:in `specs'
	from $RBENV_GEMSET_DIR/gems/bundler-1.16.2/lib/bundler/definition.rb:238:in `specs_for'
	from $RBENV_GEMSET_DIR/gems/bundler-1.16.2/lib/bundler/definition.rb:227:in `requested_specs'
	from $RBENV_GEMSET_DIR/gems/bundler-1.16.2/lib/bundler/runtime.rb:108:in `block in definition_method'
	from $RBENV_GEMSET_DIR/gems/bundler-1.16.2/lib/bundler/runtime.rb:20:in `setup'
	from $RBENV_GEMSET_DIR/gems/bundler-1.16.2/lib/bundler.rb:107:in `setup'
	from $RBENV_GEMSET_DIR/gems/bundler-1.16.2/lib/bundler/setup.rb:20:in `<top (required)>'
	from /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:127:in `require'
	from /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:127:in `rescue in require'
	from /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:40:in `require'
	from $RAILS_ROOT/config/boot.rb:3:in `<top (required)>'
	from bin/rails:3:in `require_relative'
	from bin/rails:3:in `<main>'

followed by

ERROR in ./app/javascript/i18n.js.erb
Module build failed: Error: rails-erb-loader failed with code: 1
    at ChildProcess.<anonymous> ($RAILS_ROOT/node_modules/rails-erb-loader/index.js:120:16)
    at emitTwo (events.js:126:13)
    at ChildProcess.emit (events.js:214:7)
    at maybeClose (internal/child_process.js:925:16)
    at Socket.stream.socket.on (internal/child_process.js:346:11)
    at emitOne (events.js:116:13)
    at Socket.emit (events.js:211:7)
    at Pipe._handle.close [as _onclose] (net.js:557:12)
 @ ./app/javascript/packs/frontend.js 119:0-37
 @ multi (webpack)-dev-server/client?http://0.0.0.0:8080 babel-polyfill ./app/javascript/packs/frontend.js

I’m still running Webpacker 2.0, so I could just modify my config/webpacker/loaders/erb.js:

   options: {
-    runner: 'bin/rails runner',
+    runner: 'bundle exec bin/rails runner',
   },

I don’t know, however, why this became a problem today. When working on the very same project on the same machine last week, the webpack was built without hickups…

Hi @Swat123. I don’t know why this is happening exactly, but I can explain the general context of this error message and maybe we can improve the reporting or find out what’s going wrong.

When rails-erb-loader loads a single file:

  • It runs a Ruby script in a new process. The script waits for data to be piped into it.
  • rails-erb-loader streams the input file to the process via stdin
  • The script transforms the source and prints it out.
  • rails-erb-loader reads all the stdout from the script (this will be the output)
  • When the process closes, if it ended without error (ie. returned code 0) then the loader succeeds and the transpiled source is given to webpack.

Typically with Rails you’d use bin/rails runner to execute the transformer script, and you can see that this is the approach that webpacker uses.

In short: bin/rails runner is exiting with an error code.

For @Swat123

I would have expected error output to be piped through to the main process, so you should see error logs on screen if they’re printed. Is there any logging before you see that error? If no, is it possible that the wrapper task you’re running is somehow suppressing stderr from webpack? I’m aware of webpacker’s existence, but I haven’t used it myself.

But I randomly get following error[…]

By “randomly” you mean that it only happens sometimes right? If this is the case it might be being caused by spring. You could try running the process with DISABLE_SPRING=1 and see if that stops it. It might make your build slower, but it would help explain the problem.

You can either add it to your loader config:

options: { runner: 'DISABLE_SPRING=1 bin/rails runner' }

Or you should be able to set it with your rails command:

DISABLE_SPRING=1 ruby -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) /Users/swathishah/shopify-app/bin/spring rails --trace assets:precompile

(uh… actually looking at the above you might need to remove the explicit call to spring)

Good luck!

For rails-erb-loader

Even if this issue turns out to be out of our control, I’d like to know how we can improve the error reporting from the loader. At very least we should update the error message to something like:

rails-erb-loader: “bin/rails runner” closed with exit code 1

It’s also unclear to me why the 'close' callback is being called instead of the 'error' callback.

Additionally I’d like to double check and add test coverage to ensure that we are indeed piping stderr through to the console successfully.

I’m commenting on https://github.com/usabilityhub/rails-erb-loader/issues/63#issuecomment-647127581 but it should be a starter for anyone who has issues with rails-erb :

I’m not sure if there is a conflict between Zeitwork and rails-erb-loader, but this resolved compilation errors for TWO failing js.erb files.

It’s not a conflict but the thing is : rails-erb-loader calls the rails runner command (https://guides.rubyonrails.org/command_line.html#rails-runner) to generate JS from js.erb templates.

What it says:

runner runs Ruby code in the context of Rails non-interactively

So your app must be fully functionnal before calling rake assets:precompile in any environment.

To be sure: run your app locally but in production mode (rails -e production). If you have some issues here (Rails don’t start because of Zeitwerk or any other issues like environment variables) rake assets:precompile will surely fail later. It also means that your view.js.erb file must contain valid Ruby/Rails code or it will fail too.

Technically what it does is :

# something like that
cat myfile | bin/rails runner <path to erb_transformer.rb> > output.js

https://github.com/usabilityhub/rails-erb-loader/blob/master/index.js#L21 https://github.com/usabilityhub/rails-erb-loader/blob/master/index.js#L75 https://github.com/usabilityhub/rails-erb-loader/blob/master/erb_transformer.rb

You can even try it manually 😃

We’re getting this issue on CircleCI (works fine locally) and I’ve tried every variation of running a ruby command I can think of, both in the circle.yml and the runner options.

This is what we get when rails-erb-loader tries to run.

/usr/local/lib/ruby/site_ruby/2.5.0/bundler/spec_set.rb:91:in `block in materialize': Could not find rake-12.3.1 in any of the sources (Bundler::GemNotFound)

If we take out rails-erb-loader and the one erb file, we don’t get this error. It seems to be something to do with spawning the subcommand.

I’ve tried bundle exec bin/webpack and rake webpack:compile and bin/webpack and so on, and for the options bundle exec bin/rails runner, bin/rails runner, etc.

Thanks for detailed response @n-rodriguez. This is correct (but you also need to pass “engine” and “delimiter” arguments to the erb_transformer.)

@yosupgurl In this case though there are no real surprises here (for me, the author of this module). You’re hitting issue #33. The runner doesn’t add anything to scope. You’ll see that error if you’re trying to call a function render which is not available. I don’t know how to do what you’re doing, but there is some discussion in #33 you can refer to.

We always used render at runtime for serving requests, not for baking HTML into JS strings at build time. Are you sure that’s even a good idea? Why not just inline the HTML straight into this file. Basically if you want to use webpack then you shouldn’t be using render and partial, that’s the point. Use raw-loader on a HTML file or something.

Also same general advice I gave above: This is not a good tool for web development, it’s a transitional tool for moving away from server-side helpers and into SPA land using the superior webpack system. It’s slow and bad and should really be used as minimally as possible (until someone volunteers some fixes).

FWIW, I resolved this issue by correcting a Zeitwork::NameError thrown while deploying to Heroku (Rails 6.0.3; Ruby 2.7.1p83; WSL [Ubuntu 18.04]) :

``on_file_autoloaded’: expected file /tmp/build_10e9581d550a3c3f1134ca4159ab62d0/app/controllers/admins/[snake_case].rb to define constant Admins::[CamelCase], but didn’t (Zeitwerk::NameError)`

My fix was simple: For each file that caused this error, I pluralized the module name (e.g., “Admins” instead of “Admin”) to resolve the error.

I’m not sure if there is a conflict between Zeitwork and rails-erb-loader, but this resolved compilation errors for TWO failing js.erb files.

In case it helps someone else having this issue, it was happening to me when trying to deploy to heroku using ../bin/rails runner for the runner option. Along the lines of the suggestion in https://github.com/usabilityhub/rails-erb-loader/issues/63#issuecomment-392746607 changing it to ../bin/bundle exec rails runner fixed the issue.

I have the same issue, very annoying.

ERROR in ./app/javascript/packs/serviceworker.js.erb
Module build failed (from ./node_modules/rails-erb-loader/index.js):
Error: rails-erb-loader failed with code: 1
    at ChildProcess.<anonymous> (/home/app/webapp/node_modules/rails-erb-loader/index.js:128:16)
    at ChildProcess.emit (events.js:198:13)
    at maybeClose (internal/child_process.js:982:16)
    at Socket.stream.socket.on (internal/child_process.js:389:11)
    at Socket.emit (events.js:198:13)
    at Pipe._handle.close (net.js:607:12)

I tried setting DISABLE_SPRING as well as NODE_ENV as indicated in this thread, to no avail.

This is my erb.js file:

module.exports = {
  test: /\.erb$/,
  enforce: 'pre',
  exclude: /node_modules/,
  use: [{
    loader: 'rails-erb-loader',
    options: {
      runner: 'bin/rails runner',
      env: { DISABLE_SPRING: 1, NODE_ENV: 'development' }
    }
  }]
}

I’ve also tried without the env and with preceding the DISABLE_SPRING to the runner.

I’m using version 5.5.2

For completeness this is the serviceworker.js.erb file:

var CACHE_VERSION = ‘v10’; var CACHE_NAME = CACHE_VERSION + ‘:sw-cache-’;

function onInstall(event) {
  console.log('[Serviceworker]', "Installing!", event);
  event.waitUntil(
    caches.open(CACHE_NAME).then(function prefill(cache) {
      return cache.addAll([
        <% helpers = ActionController::Base.helpers %>
        '<%= helpers.asset_pack_path "application.js" %>',
        '<%= helpers.asset_path "application.css" %>',
        '<%= helpers.asset_path "mobile.css" %>',
        '/icons/icon-white-24x24.png',
        '/icons/icon-24x24.png',
        '/icons/icon-96x96.png',
        '/apple-touch-icon.png',
        '/offline-notice.html'
      ]);
    })
  );
}

function onActivate(event) {
  console.log('[Serviceworker]', "Activating!", event);
  event.waitUntil(
    caches.keys().then(function(cacheNames) {
      return Promise.all(
        cacheNames.filter(function(cacheName) {
          // Return true if you want to remove this cache,
          // but remember that caches are shared across
          // the whole origin
          return cacheName.indexOf(CACHE_VERSION) !== 0;
        }).map(function(cacheName) {
          return caches.delete(cacheName);
        })
      );
    })
  );
}

// Borrowed from https://github.com/TalAter/UpUp
function onFetch(event) {
  event.respondWith(
    // try to return untouched request from network first
    fetch(event.request).catch(function() {
      // if it fails, try to return request from the cache
      return caches.match(event.request).then(function(response) {
        if (response) {
          return response;
        }
        // if not found in cache, return default offline content for navigate requests
        if (event.request.mode === 'navigate' ||
          (event.request.method === 'GET' && event.request.headers.get('accept').includes('text/html'))) {
          console.log('[Serviceworker]', "Fetching offline content", event);
          return caches.match('/offline-notice.html');
        }
      })
    })
  );
}

self.addEventListener("push", function (event) {
    var title = event.data.json()['title'];
    var body = event.data.json()['body'];
    var tag = event.data.json()['tag'] || '';
    var icon = event.data.json()['icon'] || '';
    var sound = event.data.json()['sound'] || '';
    var image = event.data.json()['image'] || '';
    var actions = event.data.json()['actions'] || [];
    var badge = '/icons/icon-white-24x24.png';
    var data = event.data.json()['data'] || {};
    event.waitUntil(self.registration.showNotification(title, {
        body: body,
        icon: icon,
        badge: badge,
        sound: sound,
        image: image,
        actions: actions,
        data: data,
        vibrate: [500,110,500,110,450,110,200,110,170,40,450,110,200,110,170,40,500],
        tag: tag
    }));
});

self.addEventListener('notificationclick', function(event) {
    console.log('[Nobi] Notification click Received.');
    event.waitUntil(
      clients.openWindow(event.notification.data['link'])
    );
});

self.addEventListener('install', onInstall);
self.addEventListener('activate', onActivate);
self.addEventListener('fetch', onFetch);

The webpack-dev-server is running fine, it’s only when deploying to production this is giving issues.

@bbugh also, is there any way of getting a full stack trace?

@andybluey

FYI you can always do this:

$ NODE_ENV=development npm run dev

Where dev is your dev server “script”.

@akaspick if you update to latest (5.4.2) you should get the name of the signal that killed your process in future. Hopefully you can check your production environment docs to find out what might be causing it.