evanw/esbuild · error · Error

Should be string or array of strings

Error message

Should be string or array of strings

What it means

Thrown by read_string() in scripts/uglify-tests.js:396 as the terminal fallback. The function accepts only a SimpleStatement whose body is an AST_String or an AST_Array (of strings). Any other statement shape or body node type (number, regex, call, identifier, etc.) raises this error.

Source

Thrown at scripts/uglify-tests.js:396

      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;
          }).join("\n");
      }
    }
    throw new Error("Should be string or array of strings");
  }

  function get_one_test(name, block) {
    var test = { name: name, options: {} };
    var tw = new U.TreeWalker(function (node, descend) {
      if (node instanceof U.AST_Assign) {
        if (!(node.left instanceof U.AST_SymbolRef)) {
          croak(node);
        }
        var name = node.left.name;
        test[name] = evaluate(node.right);
        return true;
      }
      if (node instanceof U.AST_LabeledStatement) {
        var label = node.label;
        assert.ok([
          "input",
          "expect",

View on GitHub (pinned to f6058f8364)

Solutions

  1. Quote the value: `expect_exact: "var a=1;";`.
  2. Use the array-of-strings form for multi-line values.
  3. Re-route the value to a field whose reader accepts the actual type.

Example fix

// before
node_version: 18;

// after
node_version: "v18";
Defensive patterns

Strategy: type-guard

Validate before calling

function isAcceptableStringField(stat) {
  if (stat.TYPE !== 'SimpleStatement') return false;
  const b = stat.body;
  return b instanceof U.AST_String || (b instanceof U.AST_Array && b.elements.every(e => e instanceof U.AST_String));
}

Type guard

const isStringOrStringArray = (stat) =>
  stat.TYPE === 'SimpleStatement' &&
  (stat.body instanceof U.AST_String ||
   (stat.body instanceof U.AST_Array && stat.body.elements.every(e => e.TYPE === 'String')));

Try / catch

try { read_string(stat); }
catch (e) {
  if (/Should be string or array of strings/.test(e.message)) console.error('Use a quoted string or array of quoted strings');
  throw e;
}

Prevention

When it happens

Trigger: Assigning a non-string to a string-routed field: `expect_exact: 42;`, `node_version: /\d+/;`, or `expect: foo;`. The harness routes expect_exact and node_version through read_string (line 426).

Common situations: Contributor uses an unquoted value, a variable, or a regex literal where a string is required.

Related errors


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