jamiebuilds/the-super-tiny-compiler · error · TypeError

node.type

Error message

node.type

What it means

traverseNode's visitor switch throws the node's type string when no case matches and there is no visitor method for that type. Out of the box the traverser handles 'NumberLiteral', 'CallExpression', and 'StringLiteral' (plus 'Program' handled specially). Any other node type in the AST — including nodes produced by a transformer or a custom parser — triggers this default throw with the node type as the message.

Source

Thrown at the-super-tiny-compiler.js:794

      case 'Program':
        traverseArray(node.body, node);
        break;

      // Next we do the same with `CallExpression` and traverse their `params`.
      case 'CallExpression':
        traverseArray(node.params, node);
        break;

      // In the cases of `NumberLiteral` and `StringLiteral` we don't have any
      // child nodes to visit, so we'll just break.
      case 'NumberLiteral':
      case 'StringLiteral':
        break;

      // And again, if we haven't recognized the node type then we'll throw an
      // error.
      default:
        throw new TypeError(node.type);
    }

    // If there is an `exit` method for this node type we'll call it with the
    // `node` and its `parent`.
    if (methods && methods.exit) {
      methods.exit(node, parent);
    }
  }

  // Finally we kickstart the traverser by calling `traverseNode` with our ast
  // with no `parent` because the top level of the AST doesn't have a parent.
  traverseNode(ast, null);
}

/**
 * ============================================================================
 *                                   ⁽(◍˃̵͈̑ᴗ˂̵͈̑)⁽
 *                              THE TRANSFORMER!!!

View on GitHub (pinned to d8d4013045)

Solutions

  1. Add a visitor method for the offending node type in the visitor object you pass to traverser() (e.g. visitor['Identifier'] = { enter() {} }) — the existing-method check runs before the switch.
  2. If maintaining a fork, add a case for the node type in traverseNode's switch before default.
  3. Verify the AST actually came from the bundled parser() and no transformer altered node.type values.
  4. If the node type is invalid, fix the upstream producer (parser or transformer) instead of the traverser.

Example fix

// before
traverser(ast, {}); // ast contains { type: 'Identifier' } -> throws TypeError: Identifier

// after
traverser(ast, {
  Identifier: {
    enter(node, parent) { /* handle or ignore */ }
  }
});
Defensive patterns

Strategy: validation

Validate before calling

const KNOWN = new Set(['Program','NumberLiteral','CallExpression','StringLiteral']);
function astIsTraversable(node, ok = true) {
  if (!node || typeof node.type !== 'string') return false;
  return KNOWN.has(node.type) && (node.body ? node.body.every(n => astIsTraversable(n)) : true);
}
if (!astIsTraversable(ast)) throw new Error('AST contains unsupported node types');
traverser(ast, visitor);

Type guard

function isKnownNodeType(node) {
  return node != null && typeof node.type === 'string' && ['Program','NumberLiteral','CallExpression','StringLiteral'].includes(node.type);
}

Try / catch

try { traverser(ast, visitor); } catch (e) { if (e instanceof TypeError && !['Program','NumberLiteral','CallExpression','StringLiteral'].includes(e.message)) { /* unknown node type: e.message; add visitor[e.message] or skip */ } else throw e; }

Prevention

When it happens

Trigger: Calling traverser(ast, visitor) on an AST containing node types other than Program/NumberLiteral/CallExpression/StringLiteral, unless the supplied visitor object has an enter/exit method keyed by that type (in which case the switch is skipped). Common with custom ASTs or transforms that add node types like 'Identifier' or 'OperatorLiteral'.

Common situations: Reusing the traverser with a custom AST from a different parser. Extending the compiler with new node types but forgetting to add cases or visitor methods. A transformer mutating node.type between enter and exit, or a previous plugin renaming types incompatibly.

Related errors


AI-assisted analysis of jamiebuilds/the-super-tiny-compiler@d8d4013045 (2026-08-28). Data as JSON: /api/errors/1ebde02338533fc5. Report an issue: GitHub.