ember-cli: On Node 15, errors during build are not recoverable

On Node 15, something that causes a build error (such as a syntax error in hbs or js) causes ember s to exit 1 when a request is made.

For example, you type part of a line of code, your editor saves, the build error displays in your log, livereload is triggered and a request is made, then the server exits 1.

Output
file changed components/selected-item.hbs.hbs
Build Error (broccoli-persistent-filter:Babel > [Babel: my-app]) in my-app/components/my-component.js

/Users/katie/dev/my-app/my-app/components/my-component.js: Parse error on line 79:
...           @extra={{(hash driveTime=@dri
-----------------------^
Expecting 'ID', 'STRING', 'NUMBER', 'BOOLEAN', 'UNDEFINED', 'NULL', 'DATA', got 'OPEN_SEXPR'


Stack Trace and Error Report: /var/folders/wq/_yzzcnwn3wlfm5x_6gg5d8vm0000gn/T/error.dump.64eb8cc3228b3c62aa5d1e0a7a89a0e7.log
node:internal/process/promises:218
          triggerUncaughtException(err, true /* fromPromise */);
          ^

BuildError: /Users/katie/dev/my-app/my-app/components/my-component.js: Parse error on line 79:
...           @extra={{(hash driveTime=@dri
-----------------------^
Expecting 'ID', 'STRING', 'NUMBER', 'BOOLEAN', 'UNDEFINED', 'NULL', 'DATA', got 'OPEN_SEXPR'
    at Parser.parseError (/Users/katie/dev/my-app/node_modules/ember-source/dist/ember-template-compiler.js:13397:15)
    at Parser.parse (/Users/katie/dev/my-app/node_modules/ember-source/dist/ember-template-compiler.js:13472:20)
    at parseWithoutProcessing (/Users/katie/dev/my-app/node_modules/ember-source/dist/ember-template-compiler.js:14657:26)
    at parse (/Users/katie/dev/my-app/node_modules/ember-source/dist/ember-template-compiler.js:14662:15)
    at preprocess (/Users/katie/dev/my-app/node_modules/ember-source/dist/ember-template-compiler.js:8885:35)
    at precompile (/Users/katie/dev/my-app/node_modules/ember-source/dist/ember-template-compiler.js:6103:38)
    at precompile (/Users/katie/dev/my-app/node_modules/ember-source/dist/ember-template-compiler.js:11500:37)
    at compileTemplate (/Users/katie/dev/my-app/node_modules/babel-plugin-htmlbars-inline-precompile/index.js:66:26)
    at PluginPass.CallExpression (/Users/katie/dev/my-app/node_modules/babel-plugin-htmlbars-inline-precompile/index.js:226:26)
    at newFn (/Users/katie/dev/my-app/node_modules/@babel/traverse/lib/visitors.js:175:21) {
  isBuilderError: true,
  isSilent: undefined,
  isCancellation: undefined,
  broccoliPayload: {
    originalError: Error: /Users/katie/dev/my-app/my-app/components/my-component.js: Parse error on line 79:
    ...           @extra={{(hash driveTime=@dri
    -----------------------^
    Expecting 'ID', 'STRING', 'NUMBER', 'BOOLEAN', 'UNDEFINED', 'NULL', 'DATA', got 'OPEN_SEXPR'
        at Parser.parseError (/Users/katie/dev/my-app/node_modules/ember-source/dist/ember-template-compiler.js:13397:15)
        at Parser.parse (/Users/katie/dev/my-app/node_modules/ember-source/dist/ember-template-compiler.js:13472:20)
        at parseWithoutProcessing (/Users/katie/dev/my-app/node_modules/ember-source/dist/ember-template-compiler.js:14657:26)
        at parse (/Users/katie/dev/my-app/node_modules/ember-source/dist/ember-template-compiler.js:14662:15)
        at preprocess (/Users/katie/dev/my-app/node_modules/ember-source/dist/ember-template-compiler.js:8885:35)
        at precompile (/Users/katie/dev/my-app/node_modules/ember-source/dist/ember-template-compiler.js:6103:38)
        at precompile (/Users/katie/dev/my-app/node_modules/ember-source/dist/ember-template-compiler.js:11500:37)
        at compileTemplate (/Users/katie/dev/my-app/node_modules/babel-plugin-htmlbars-inline-precompile/index.js:66:26)
        at PluginPass.CallExpression (/Users/katie/dev/my-app/node_modules/babel-plugin-htmlbars-inline-precompile/index.js:226:26)
        at newFn (/Users/katie/dev/my-app/node_modules/@babel/traverse/lib/visitors.js:175:21) {
      code: 'BABEL_TRANSFORM_ERROR',
      file: 'my-app/components/my-component.js',
      treeDir: '/var/folders/wq/_yzzcnwn3wlfm5x_6gg5d8vm0000gn/T/broccoli-22626Xituejlbzweg/out-549-analyzer_ember_auto_import_analyzer'
    },
    originalMessage: '/Users/katie/dev/my-app/my-app/components/my-component.js: Parse error on line 79:\n' +
      '...           @extra={{(hash driveTime=@dri\n' +
      '-----------------------^\n' +
      "Expecting 'ID', 'STRING', 'NUMBER', 'BOOLEAN', 'UNDEFINED', 'NULL', 'DATA', got 'OPEN_SEXPR'",
    nodeId: 550,
    nodeLabel: 'broccoli-persistent-filter:Babel > [Babel: my-app] (Babel: my-app)',
    nodeName: 'broccoli-persistent-filter:Babel > [Babel: my-app]',
    nodeAnnotation: 'Babel: my-app',
    instantiationStack: '    at Babel.Plugin (/Users/katie/dev/my-app/node_modules/broccoli-plugin/index.js:7:31)\n' +
      '    at Babel.Filter [as constructor] (/Users/katie/dev/my-app/node_modules/broccoli-persistent-filter/index.js:87:10)\n' +
      '    at new Babel (/Users/katie/dev/my-app/node_modules/ember-cli-babel/node_modules/broccoli-babel-transpiler/index.js:58:10)\n' +
      '    at Class.transpileTree (/Users/katie/dev/my-app/node_modules/ember-cli-babel/index.js:63:16)\n' +
      '    at Object.toTree (/Users/katie/dev/my-app/node_modules/ember-cli-babel/index.js:73:30)\n' +
      '    at /Users/katie/dev/my-app/node_modules/ember-cli-preprocess-registry/preprocessors.js:188:26\n' +
      '    at Array.forEach (<anonymous>)\n' +
      '    at processPlugins (/Users/katie/dev/my-app/node_modules/ember-cli-preprocess-registry/preprocessors.js:186:11)\n' +
      '    at module.exports.preprocessJs (/Users/katie/dev/my-app/node_modules/ember-cli-preprocess-registry/preprocessors.js:179:10)\n' +
      '    at DefaultPackager.processJavascript (/Users/katie/dev/my-app/node_modules/ember-cli/lib/broccoli/default-packager.js:503:29)',
    location: {
      file: 'my-app/components/my-component.js',
      treeDir: '/var/folders/wq/_yzzcnwn3wlfm5x_6gg5d8vm0000gn/T/broccoli-22626Xituejlbzweg/out-549-analyzer_ember_auto_import_analyzer',
      line: undefined,
      column: undefined
    },
    error: {
      message: '/Users/katie/dev/my-app/my-app/components/my-component.js: Parse error on line 79:\n' +
        '...           @extra={{(hash driveTime=@dri\n' +
        '-----------------------^\n' +
        "Expecting 'ID', 'STRING', 'NUMBER', 'BOOLEAN', 'UNDEFINED', 'NULL', 'DATA', got 'OPEN_SEXPR'",
      stack: 'Error: /Users/katie/dev/my-app/my-app/components/my-component.js: Parse error on line 79:\n' +
        '...           @extra={{(hash driveTime=@dri\n' +
        '-----------------------^\n' +
        "Expecting 'ID', 'STRING', 'NUMBER', 'BOOLEAN', 'UNDEFINED', 'NULL', 'DATA', got 'OPEN_SEXPR'\n" +
        '    at Parser.parseError (/Users/katie/dev/my-app/node_modules/ember-source/dist/ember-template-compiler.js:13397:15)\n' +
        '    at Parser.parse (/Users/katie/dev/my-app/node_modules/ember-source/dist/ember-template-compiler.js:13472:20)\n' +
        '    at parseWithoutProcessing (/Users/katie/dev/my-app/node_modules/ember-source/dist/ember-template-compiler.js:14657:26)\n' +
        '    at parse (/Users/katie/dev/my-app/node_modules/ember-source/dist/ember-template-compiler.js:14662:15)\n' +
        '    at preprocess (/Users/katie/dev/my-app/node_modules/ember-source/dist/ember-template-compiler.js:8885:35)\n' +
        '    at precompile (/Users/katie/dev/my-app/node_modules/ember-source/dist/ember-template-compiler.js:6103:38)\n' +
        '    at precompile (/Users/katie/dev/my-app/node_modules/ember-source/dist/ember-template-compiler.js:11500:37)\n' +
        '    at compileTemplate (/Users/katie/dev/my-app/node_modules/babel-plugin-htmlbars-inline-precompile/index.js:66:26)\n' +
        '    at PluginPass.CallExpression (/Users/katie/dev/my-app/node_modules/babel-plugin-htmlbars-inline-precompile/index.js:226:26)\n' +
        '    at newFn (/Users/katie/dev/my-app/node_modules/@babel/traverse/lib/visitors.js:175:21)',
      errorType: 'Build Error',
      codeFrame: '/Users/katie/dev/my-app/my-app/components/my-component.js: Parse error on line 79:\n' +
        '...           @extra={{(hash driveTime=@dri\n' +
        '-----------------------^\n' +
        "Expecting 'ID', 'STRING', 'NUMBER', 'BOOLEAN', 'UNDEFINED', 'NULL', 'DATA', got 'OPEN_SEXPR'",
      location: {
        file: 'my-app/components/my-component.js',
        treeDir: '/var/folders/wq/_yzzcnwn3wlfm5x_6gg5d8vm0000gn/T/broccoli-22626Xituejlbzweg/out-549-analyzer_ember_auto_import_analyzer',
        line: undefined,
        column: undefined
      }
    },
    broccoliNode: {
      nodeName: 'broccoli-persistent-filter:Babel > [Babel: my-app]',
      nodeAnnotation: 'Babel: my-app',
      instantiationStack: '    at Babel.Plugin (/Users/katie/dev/my-app/node_modules/broccoli-plugin/index.js:7:31)\n' +
        '    at Babel.Filter [as constructor] (/Users/katie/dev/my-app/node_modules/broccoli-persistent-filter/index.js:87:10)\n' +
        '    at new Babel (/Users/katie/dev/my-app/node_modules/ember-cli-babel/node_modules/broccoli-babel-transpiler/index.js:58:10)\n' +
        '    at Class.transpileTree (/Users/katie/dev/my-app/node_modules/ember-cli-babel/index.js:63:16)\n' +
        '    at Object.toTree (/Users/katie/dev/my-app/node_modules/ember-cli-babel/index.js:73:30)\n' +
        '    at /Users/katie/dev/my-app/node_modules/ember-cli-preprocess-registry/preprocessors.js:188:26\n' +
        '    at Array.forEach (<anonymous>)\n' +
        '    at processPlugins (/Users/katie/dev/my-app/node_modules/ember-cli-preprocess-registry/preprocessors.js:186:11)\n' +
        '    at module.exports.preprocessJs (/Users/katie/dev/my-app/node_modules/ember-cli-preprocess-registry/preprocessors.js:179:10)\n' +
        '    at DefaultPackager.processJavascript (/Users/katie/dev/my-app/node_modules/ember-cli/lib/broccoli/default-packager.js:503:29)'
    },
    versions: { 'broccoli-builder': '3.4.2', node: 'v15.2.1' }
  }
}

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 4
  • Comments: 18 (9 by maintainers)

Commits related to this issue

Most upvoted comments

For those who must use Node 15 already (hello M1 Macs), a workaround is adding a global exception handler:

process.on('uncaughtException', function(err) {
  console.error(err.stack);
  console.log('Node NOT Exiting...');
});

to your ember-cli-build.js (or any other file ran through Node on build).

With node 16.13.1:

TypeError [ERR_INVALID_ARG_TYPE]: The "options" argument must be of type object. Received an instance of Array
    at ChildProcess.target.send (node:internal/child_process:713:7)
    at Array.forEach (<anonymous>)
    at dispatchQueuedRequests (/Users/mileslane/Projects/clear_value_plus/ember/reference-ui/node_modules/ember-cli-airbrake/node_modules/workerpool/lib/WorkerHandler.js:174:21)
    at ChildProcess.<anonymous> (/Users/mileslane/Projects/clear_value_plus/ember/reference-ui/node_modules/ember-cli-airbrake/node_modules/workerpool/lib/WorkerHandler.js:129:7)
    at ChildProcess.emit (node:events:390:28)
    at emit (node:internal/child_process:917:12)
    at processTicksAndRejections (node:internal/process/task_queues:84:21) {
  code: 'ERR_INVALID_ARG_TYPE'

FWIW: I’m not using the solution posted above anymore, patching local ember-cli-build.js and workerpool NPM package

Now I’m preloading the following script with required monkey-patches, using NODE_OPTIONS env. var:

// For Ember on Node.js 15+, set in NODE_OPTIONS:
// export NODE_OPTIONS="--require /Users/bardzusny/node-15-for-ember-monkeypatching.js"

// 1. Don't exit Node process on uncaught exceptions, keeping Node 14 behaviour. Required to not crash Ember server on type errors thrown by ember-cli-typescript
process.on("uncaughtException", function (err) {
  console.error(err.stack);
  console.log("Node NOT Exiting...");
});

// 2. Monkey-patching Array.prototype.forEach: to detect specific build step call from a specific file, based on a stack trace - and add special sauce for it to work OK with Node 15+:
//
// Error
// at Array.forEach (/Users/bardzusny/this-file.js:24:17)
// at dispatchQueuedRequests (/Users/bardzusny/code/ember-app/node_modules/workerpool/lib/WorkerHandler.js:240:21)
// ...

let specialForEachRegexp = new RegExp(
  "at dispatchQueuedRequests.*node_modules/workerpool/lib/WorkerHandler.js"
);

let origForEach = Array.prototype.forEach;

Array.prototype.forEach = function () {
  if (specialForEachRegexp.test(new Error().stack.split("\n")[2])) {
    let sendFunc = arguments[0];
    return origForEach.bind(this)((req) => sendFunc(req)); // sendFunc must receive only one argument, otherwise it errors out
  }

  return origForEach.bind(this)(...arguments);
};

And that’s it -> now Ember server should work all right with Node 15/16. (3.24 here, with plenty of legacy addons.)

@12finger it’s 3.24, so like current super-rentals repo.

What I posted fixes issue discussed here, but indeed isn’t the whole story to get a real Ember project running with Node 15. On a super-rentals app example, the error you’ve probably got is:

TypeError [ERR_INVALID_ARG_TYPE]: The "options" argument must be of type object. Received an instance of Array
    at ChildProcess.target.send (node:internal/child_process:716:7)
    at Array.forEach (<anonymous>)
    at dispatchQueuedRequests (/Users/bardzusny/code/super-rentals/node_modules/ember-inflector/node_modules/workerpool/lib/WorkerHandler.js:174:21)
    at ChildProcess.<anonymous> (/Users/bardzusny/code/super-rentals/node_modules/ember-inflector/node_modules/workerpool/lib/WorkerHandler.js:129:7)
    at ChildProcess.emit (node:events:378:20)
    at ChildProcess.EventEmitter.emit (node:domain:470:12)
    at emit (node:internal/child_process:920:12)
    at processTicksAndRejections (node:internal/process/task_queues:82:21) {
  code: 'ERR_INVALID_ARG_TYPE'
}

To fix it, I backported the erroring function from the latest workerpool package release.

Save the following diff to some file, e.g. fix-workerpool.patch:

diff --git a/node_modules/ember-inflector/node_modules/workerpool/lib/WorkerHandler.js b/node_modules/ember-inflector/node_modules/workerpool/lib/WorkerHandler.js
index 02f748a..bdcc0c6 100644
--- a/node_modules/ember-inflector/node_modules/workerpool/lib/WorkerHandler.js
+++ b/node_modules/ember-inflector/node_modules/workerpool/lib/WorkerHandler.js
@@ -171,8 +171,9 @@ function WorkerHandler(script, options) {
   // send all queued requests to worker
   function dispatchQueuedRequests()
   {
-    me.requestQueue.forEach(me.worker.send.bind(me.worker));
-    me.requestQueue = [];
+    for (const request of me.requestQueue.splice(0)) {
+      me.worker.send(request);
+    }
   }

   // listen for worker messages error and exit

And then apply it to your project:

git apply .../fix-workerpool.patch

(You’ll need to repeat this call after every npm install.)

I consider those typical early adopter pains. Expecting them to get fixed once Node 16 (next LTS) is out, ember-cli starts supporting it.

Node 16.15.0 also is affected:

TypeError [ERR_INVALID_ARG_TYPE]: The "options" argument must be of type object. Received an instance of Array
    at ChildProcess.target.send (node:internal/child_process:733:7)
    at Array.forEach (<anonymous>)
    at dispatchQueuedRequests (F:\repos\FinlayDaG33k\dashboard\node_modules\ember-cli-test-loader\node_modules\workerpool\lib\WorkerHandler.js:174:21)
    at ChildProcess.<anonymous> (F:\repos\FinlayDaG33k\dashboard\node_modules\ember-cli-test-loader\node_modules\workerpool\lib\WorkerHandler.js:129:7)
    at ChildProcess.emit (node:events:527:28)
    at ChildProcess.emit (node:domain:475:12)
    at emit (node:internal/child_process:938:14)
    at processTicksAndRejections (node:internal/process/task_queues:84:21) {
  code: 'ERR_INVALID_ARG_TYPE'
}

FYI - We are working toward a solution RE: ember-cli-babel@6 users (the workerpool issue) over in https://github.com/babel/broccoli-babel-transpiler/pull/203.

I think people have been getting trolled by the stack trace. The HTTP server is re-throwing an older build error to cause this process.exit. So the stack trace you see has nothing to do with the code that is doing the re-throwing, which is the code that needs to be fixed. I am digging in.

Same error with node 16.13.1 my deployments started to fail when GitHub rolled out nodejs 16 on their GitHub action images for runners.