{"record":{"id":"d32952bff10550a9","repo":"evanw/esbuild","slug":"should-be-string-or-array-of-strings-d32952","errorCode":null,"errorMessage":"Should be string or array of strings","messagePattern":"Should be string or array of strings","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/uglify-tests.js","lineNumber":396,"sourceCode":"      code: make_code(node, { beautify: false })\n    }));\n  }\n\n  function read_string(stat) {\n    if (stat.TYPE == \"SimpleStatement\") {\n      var body = stat.body;\n      switch (body.TYPE) {\n        case \"String\":\n          return body.value;\n        case \"Array\":\n          return body.elements.map(function (element) {\n            if (element.TYPE !== \"String\")\n              throw new Error(\"Should be array of strings\");\n            return element.value;\n          }).join(\"\\n\");\n      }\n    }\n    throw new Error(\"Should be string or array of strings\");\n  }\n\n  function get_one_test(name, block) {\n    var test = { name: name, options: {} };\n    var tw = new U.TreeWalker(function (node, descend) {\n      if (node instanceof U.AST_Assign) {\n        if (!(node.left instanceof U.AST_SymbolRef)) {\n          croak(node);\n        }\n        var name = node.left.name;\n        test[name] = evaluate(node.right);\n        return true;\n      }\n      if (node instanceof U.AST_LabeledStatement) {\n        var label = node.label;\n        assert.ok([\n          \"input\",\n          \"expect\",","sourceCodeStart":378,"sourceCodeEnd":414,"githubUrl":"https://github.com/evanw/esbuild/blob/f6058f8364fe7ab91ca57a83e02577ed74c9cae4/scripts/uglify-tests.js#L378-L414","documentation":"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.","triggerScenarios":"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).","commonSituations":"Contributor uses an unquoted value, a variable, or a regex literal where a string is required.","solutions":["Quote the value: `expect_exact: \"var a=1;\";`.","Use the array-of-strings form for multi-line values.","Re-route the value to a field whose reader accepts the actual type."],"exampleFix":"// before\nnode_version: 18;\n\n// after\nnode_version: \"v18\";","handlingStrategy":"type-guard","validationCode":"function isAcceptableStringField(stat) {\n  if (stat.TYPE !== 'SimpleStatement') return false;\n  const b = stat.body;\n  return b instanceof U.AST_String || (b instanceof U.AST_Array && b.elements.every(e => e instanceof U.AST_String));\n}","typeGuard":"const isStringOrStringArray = (stat) =>\n  stat.TYPE === 'SimpleStatement' &&\n  (stat.body instanceof U.AST_String ||\n   (stat.body instanceof U.AST_Array && stat.body.elements.every(e => e.TYPE === 'String')));","tryCatchPattern":"try { read_string(stat); }\ncatch (e) {\n  if (/Should be string or array of strings/.test(e.message)) console.error('Use a quoted string or array of quoted strings');\n  throw e;\n}","preventionTips":["Always quote values for expect_exact / node_version fields.","Reach for the array form only for multi-line strings."],"tags":["test-harness","uglify","validation","string","contributor"],"backgroundTag":null,"analyzedSha":"f6058f8364fe7ab91ca57a83e02577ed74c9cae4","analyzedAt":"2026-08-09T18:37:22.223Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}