emberjs/ember.js · error · Exception

${node.type} requires ${name}

Error message

${node.type} requires ${name}

What it means

acceptRequired traverses a required key and then asserts the key still holds a truthy value — guarding against transforms or visitors that delete required child nodes (like a BlockStatement's path or program). If the key is empty after traversal, the node is structurally invalid and it throws '<NodeType> requires <name>'.

Source

Thrown at packages/@handlebars/parser/lib/visitor.js:37

          'Unexpected node type "' +
            value.type +
            '" found when accepting ' +
            name +
            ' on ' +
            node.type
        );
      }
      node[name] = value;
    }
  },

  // Performs an accept operation with added sanity check to ensure
  // required keys are not removed.
  acceptRequired: function (node, name) {
    this.acceptKey(node, name);

    if (!node[name]) {
      throw new Exception(node.type + ' requires ' + name);
    }
  },

  // Traverses a given array. If mutating, empty responses will be removed
  // for child elements.
  acceptArray: function (array) {
    for (let i = 0, l = array.length; i < l; i++) {
      this.acceptKey(array, i);

      if (!array[i]) {
        array.splice(i, 1);
        i--;
        l--;
      }
    }
  },

  accept: function (object) {

View on GitHub (pinned to 26f97246a8)

Solutions

  1. Stop deleting required keys in your visitor; return the node unchanged if you meant 'no-op'
  2. Replace the node's parent entry instead of emptying a required field
  3. Ensure handler functions return a valid replacement node, not undefined
  4. Add an AST assertion pass after your transform to catch corruption early

Example fix

// before
visit: { PathExpression() { return null; } }
// after
visit: { PathExpression(node) { return node; } }
Defensive patterns

Strategy: validation

Validate before calling

const REQUIRED = { BlockStatement: ['path','program'], PartialBlockStatement: ['path','program'], Program: ['body'] };
Object.entries(REQUIRED).forEach(([t, keys]) => keys.forEach(k => { if (astNodes.some(n => n.type === t && !n[k])) throw new Error(t + ' requires ' + k); }));

Try / catch

try { visitor.visit(ast); } catch (e) { if (/ requires /.test(e.message)) { console.error('Transform removed a required key:', e.message); } throw e; }

Prevention

When it happens

Trigger: A mutating visitor returns null/undefined or deletes node[name] for a required key (e.g. removing node.path or node.program from a BlockStatement) during traversal.

Common situations: Codemods/whitespace-strip passes removing 'empty' nodes that are actually required; custom plugins returning undefined from handlers; refactor tools rewriting AST sections.

Related errors


AI-assisted analysis of emberjs/ember.js@26f97246a8 (2026-09-01). Data as JSON: /api/errors/c972008bacb9b312. Report an issue: GitHub.