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 uglify test harness (scripts/uglify-tests.js:374). Identical in purpose to the terser variant: the AST TreeWalker expects every top-level node to be an AST_LabeledStatement; any other node type besides AST_Toplevel causes the harness to reject the file as malformed, reporting file, line, column, and the offending code.

Source

Thrown at scripts/uglify-tests.js:374

  }
  var tests = Object.create(null);
  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_string(stat) {
    if (stat.TYPE == "SimpleStatement") {
      var body = stat.body;
      switch (body.TYPE) {
        case "String":
          return body.value;
        case "Array":
          return body.elements.map(function (element) {
            if (element.TYPE !== "String")
              throw new Error("Should be array of strings");
            return element.value;

View on GitHub (pinned to f6058f8364)

Solutions

  1. Inspect the file/line/column in the message and make the offending top-level construct a labeled test block.
  2. For assignment errors, ensure the left-hand side is a bare symbol reference.
  3. If uglify's test format changed, extend parse_test/get_one_test to handle the new node type.

Example fix

// before
function helper() { return 1 }
my_test: { input: { a: helper() }; expect: { a: 1 } }

// after
my_test: { input: { a: 1 }; expect: { a: 1 } }
Defensive patterns

Strategy: validation

Validate before calling

function validateUglifyTestFile(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 { parse_test(file); }
catch (e) {
  if (/Can't understand test file/.test(e.message)) console.error('Malformed uglify test file:', e.message);
  throw e;
}

Prevention

When it happens

Trigger: An uglify compress-test file has top-level content that is not a `label: { ... }` test block, or an AST_Assign inside a block has a left-hand side that is not an AST_SymbolRef (croak is called at line 404).

Common situations: Contributor adds a helper function, import, or stray statement at the top of an uglify test file, or uglify's DSL changes shape in a way the copied harness code does not understand.

Related errors


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