{"record":{"id":"b552624852f61e04","repo":"karatelabs/karate","slug":"string-raw-raw-must-be-an-object","errorCode":null,"errorMessage":"String.raw .raw must be an object","messagePattern":"String\\.raw \\.raw must be an object","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/JsStringConstructor.java","lineNumber":97,"sourceCode":"        return sb.toString();\n    }\n\n    // Spec §22.1.2.4 — String.raw(template, ...substitutions). Walks\n    // template.raw[k] for k in [0, length), interleaving substitutions[k] from\n    // the second arg onward. Coercion goes through the spec ToString helper so\n    // host objects with a JS toString return user-visible strings, and\n    // non-array-like raw values (length=NaN/0) fall through to the empty\n    // string per §22.1.2.4 step 6 / 8.\n    private Object raw(Context context, Object[] args) {\n        Object template = args.length > 0 ? args[0] : Terms.UNDEFINED;\n        Terms.requireObjectCoercible(template, \"String.raw\");\n        if (!(template instanceof ObjectLike templateObj)) {\n            throw JsErrorException.typeError(\"String.raw template must be an object\");\n        }\n        Object rawObj = templateObj.getMember(\"raw\");\n        Terms.requireObjectCoercible(rawObj, \"String.raw .raw\");\n        if (!(rawObj instanceof ObjectLike raw)) {\n            throw JsErrorException.typeError(\"String.raw .raw must be an object\");\n        }\n        CoreContext cc = context instanceof CoreContext c ? c : null;\n        // Spec ToLength(raw.length): NaN / negative / undefined → 0.\n        double rawLen = Terms.objectToNumber(raw.getMember(\"length\")).doubleValue();\n        if (Double.isNaN(rawLen) || rawLen <= 0) return \"\";\n        long length = rawLen >= Integer.MAX_VALUE ? Integer.MAX_VALUE : (long) rawLen;\n        StringBuilder sb = new StringBuilder();\n        for (long i = 0; i < length; i++) {\n            sb.append(Terms.toStringCoerce(raw.getMember(Long.toString(i)), cc));\n            if (i + 1 == length) break;\n            // substitutions are positional starting at args[1].\n            int subIdx = (int) (i + 1);\n            if (subIdx < args.length) {\n                sb.append(Terms.toStringCoerce(args[subIdx], cc));\n            }\n        }\n        return sb.toString();\n    }","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/JsStringConstructor.java#L79-L115","documentation":"This TypeError is thrown by String.raw when the 'raw' property of the template object is not itself an object. The spec requires call(template.raw) where raw must be an Object-like carrying a 'length' and indexed elements. A raw value that is a string, number, or undefined-but-coercible value triggers this error.","triggerScenarios":"Calling String.raw({ raw: 'abc' }) — a string raw is rejected — or String.raw({}) where raw is undefined (after requireObjectCoercible on undefined), or passing an object whose raw property was overwritten with a non-object.","commonSituations":"Hand-built template-like objects for testing; destructured or serialized template objects losing the raw array; mock libraries that approximate template objects incorrectly.","solutions":["Give the template object an array (or object with length) as raw: { raw: ['a','b'] }","Check Array.isArray(template.raw) before calling String.raw","Use an actual tagged template literal so the runtime builds a correct template object"],"exampleFix":"// before\nString.raw({ raw: 'abc' }); // TypeError\n// after\nString.raw({ raw: ['a', 'b', 'c'] }); // 'abc'","handlingStrategy":"type-guard","validationCode":"const hasRawObject = (t) => t !== null && typeof t === 'object' && t.raw !== null && typeof t.raw === 'object';","typeGuard":"const isRawTemplate = (t) => typeof t === 'object' && t !== null && typeof t.raw === 'object' && t.raw !== null && typeof t.raw.length === 'number';","tryCatchPattern":"try { return String.raw(template); } catch (e) { if (e instanceof TypeError) return ''; throw e; }","preventionTips":["Ensure raw is an array of string parts, not a single string","Keep template objects intact through serialization/destructuring","Add a shape assertion when constructing template-like mocks"],"tags":["javascript","string","type-error","template-literals"],"backgroundTag":"invalid-argument-value","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}