{"record":{"id":"d959430b95630ccf","repo":"karatelabs/karate","slug":"symbol-toprimitive-method-is-not-callable","errorCode":null,"errorMessage":"Symbol.toPrimitive method is not callable","messagePattern":"Symbol\\.toPrimitive method is not callable","errorType":"exception","errorClass":"JsErrorException (typeError)","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/Terms.java","lineNumber":1345,"sourceCode":"            return jp.getJavaValue();\n        }\n        if (value instanceof BigInteger || isPrimitive(value)) {\n            return value;\n        }\n        // ObjectLike (or Java-native types we wrap): run OrdinaryToPrimitive.\n        ObjectLike ol = (value instanceof ObjectLike) ? (ObjectLike) value : toObjectLike(value);\n        if (ol == null || context == null) {\n            // No prototype dispatch possible — return as-is and let the caller cope.\n            return value;\n        }\n        // Spec: @@toPrimitive (the well-known Symbol.toPrimitive method) takes precedence\n        // over OrdinaryToPrimitive's valueOf/toString dispatch. Hint passed verbatim\n        // (\"string\" | \"number\" | \"default\"). Result must be a primitive; an object result\n        // is a TypeError per spec. Set-but-not-callable is also a TypeError (GetMethod).\n        Object exotic = ol.getMember(\"@@toPrimitive\");\n        if (exotic != null && exotic != UNDEFINED) {\n            if (!(exotic instanceof JsCallable jsc)) {\n                throw JsErrorException.typeError(\"Symbol.toPrimitive method is not callable\");\n            }\n            CoreContext callCtx = new CoreContext(context, null, null);\n            callCtx.thisObject = ol;\n            String hintArg = hint == null ? \"default\" : hint;\n            Object r = jsc.call(callCtx, new Object[]{hintArg});\n            if (callCtx.isError()) {\n                context.updateFrom(callCtx);\n                return UNDEFINED;\n            }\n            if (r == null || r == UNDEFINED || isPrimitive(r) || r instanceof BigInteger) {\n                return r;\n            }\n            throw JsErrorException.typeError(\"Cannot convert object to primitive value\");\n        }\n        return ordinaryToPrimitive(ol, hint, context);\n    }\n\n    /**","sourceCodeStart":1327,"sourceCodeEnd":1363,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/Terms.java#L1327-L1363","documentation":"When an object defines @@toPrimitive, the spec's GetMethod requires it to be callable. Terms.java throws this TypeError when Symbol.toPrimitive exists but is not a function (e.g. a number, string, or plain object), instead of ignoring it.","triggerScenarios":"An object in karate-js has a non-callable `Symbol.toPrimitive` member and is then used in arithmetic, comparison, or string coercion that triggers ToPrimitive with a hint.","commonSituations":"Typos like `{ [Symbol.toPrimitive]: 'number' }`, assigning the symbol itself instead of a function, or JSON/config data accidentally overwriting the well-known symbol property.","solutions":["Make @@toPrimitive a function: { [Symbol.toPrimitive]: (hint) => ... }","Remove the property if custom conversion isn't intended, letting valueOf/toString handle coercion","Guard in library code: check typeof obj[Symbol.toPrimitive] === 'function' before relying on it"],"exampleFix":"// before\nconst o = { [Symbol.toPrimitive]: '42' };\n// after\nconst o = { [Symbol.toPrimitive]: (hint) => '42' };","handlingStrategy":"validation","validationCode":"const tp = obj[Symbol.toPrimitive];\nif (tp !== undefined && typeof tp !== 'function') throw new Error('Symbol.toPrimitive must be callable');","typeGuard":"function hasCallableToPrimitive(o) { return o == null || typeof o[Symbol.toPrimitive] === 'function' || o[Symbol.toPrimitive] === undefined; }","tryCatchPattern":"try { n = obj + 0; } catch (e) { if (String(e).includes('not callable')) n = Number(obj.valueOf ? obj.valueOf() : obj); else throw e; }","preventionTips":["Assign functions (not values) to Symbol.toPrimitive","Don't build objects from raw JSON that might overwrite well-known symbols","Type-check computed object literals in test scripts"],"tags":["javascript","symbol","to-primitive"],"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-19T12:17:13.211Z"}