evanw/esbuild · error · Error

Can't understand test file {file} [{line},{col}] {code}

Error message

Can't understand test file {file} [{line},{col}]
{code}

What it means

Thrown by croak() inside parse_test() in esbuild's terser test harness (scripts/terser-tests.js:253). The harness walks the parsed AST of a terser compress-test file with a TreeWalker; every top-level node is expected to be an AST_LabeledStatement (a named test block). If the walker reaches any other node type besides AST_Toplevel, the test-file structure is considered unparseable and this error is raised with the offending file, line, column, and code snippet.

Source

Thrown at scripts/terser-tests.js:253

  }
  var tests = {};
  var tw = new U.TreeWalker(function (node, descend) {
    if (node instanceof U.AST_LabeledStatement
      && tw.parent() instanceof U.AST_Toplevel) {
      var name = node.label.name;
      if (name in tests) {
        throw new Error('Duplicated test name "' + name + '" in ' + file);
      }
      tests[name] = get_one_test(name, node.body);
      return true;
    }
    if (!(node instanceof U.AST_Toplevel)) croak(node);
  });
  ast.walk(tw);
  return tests;

  function croak(node) {
    throw new Error(tmpl("Can't understand test file {file} [{line},{col}]\n{code}", {
      file: file,
      line: node.start.line,
      col: node.start.col,
      code: make_code(node, { beautify: false })
    }));
  }

  function read_boolean(stat) {
    if (stat.TYPE == "SimpleStatement") {
      var body = stat.body;
      if (body instanceof U.AST_Boolean) {
        return body.value;
      }
    }
    throw new Error("Should be boolean");
  }

  function read_string(stat) {

View on GitHub (pinned to f6058f8364)

Solutions

  1. Open the file/line reported in the message and confirm every top-level construct is a labeled test block (`testName: { input: ...; expect: ... }`).
  2. If the offending node is an assignment, ensure its left-hand side is a bare symbol reference, not a member expression or destructuring pattern.
  3. If terser changed its test-file DSL, extend get_one_test/parse_test in scripts/terser-tests.js to handle the new node shape.
  4. Re-run `node scripts/terser-tests.js` to confirm the file now parses.

Example fix

// before (top-level bare statement breaks parser)
console.log('setup');
my_test: {
  input: { a: 1 };
  expect: { a: 1 };
}

// after (everything is a labeled test block)
my_test: {
  input: { a: 1 };
  expect: { a: 1 };
}
Defensive patterns

Strategy: validation

Validate before calling

// Before walking, confirm every top-level AST node is a labeled statement
const U = require('uglify-js');
function validateTerserTestFile(file) {
  const ast = U.parse(fs.readFileSync(file, 'utf8'), { filename: file });
  for (const stmt of ast.body) {
    if (!(stmt instanceof U.AST_LabeledStatement)) {
      throw new Error(`${file}:${stmt.start.line}:${stmt.start.col} top-level node is not a labeled test block`);
    }
  }
}

Type guard

const isLabeledTopLevel = (node, parent) =>
  node instanceof U.AST_LabeledStatement && parent instanceof U.AST_Toplevel;

Try / catch

try {
  const tests = parse_test(file);
} catch (e) {
  if (/Can't understand test file/.test(e.message)) {
    console.error('Test file is malformed:', e.message); // fix the file, do not swallow
  }
  throw e;
}

Prevention

When it happens

Trigger: A terser test file (consumed by scripts/terser-tests.js) contains a top-level statement that is not a label:test block — e.g. a bare function declaration, import, or stray expression at the top of the file. It is also hit if an AST_Assign's left side is not an AST_SymbolRef (the harness calls croak(node) at line 297 for malformed assignments).

Common situations: Contributors porting a new terser test case forget the required `name: { ... }` labeled-statement form, or a terser upstream format change adds top-level declarations the harness does not recognize. A syntax error that still parses to an unexpected node shape also surfaces here.

Related errors


AI-assisted analysis of evanw/esbuild@f6058f8364 (2026-08-09). Data as JSON: /api/errors/23f8d71cda4e5f6c. Report an issue: GitHub.