{"record":{"id":"f50e53d8dd90c8bd","repo":"karatelabs/karate","slug":"cannot-mix-bigint-and-other-types-use-explicit-conversions-f50e53","errorCode":null,"errorMessage":"Cannot mix BigInt and other types, use explicit conversions (+)","messagePattern":"Cannot mix BigInt and other types, use explicit conversions \\(\\+\\)","errorType":"exception","errorClass":"JsErrorException (typeError)","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/Terms.java","lineNumber":835,"sourceCode":"    static Object add(Object lhs, Object rhs, CoreContext context) {\n        // Spec evaluation of binary +: ToPrimitive both operands first (default hint),\n        // then string-or-number dispatch on the *primitives*. ObjectLike on either side\n        // is the rare case — primitives short-circuit through the existing fast path.\n        if (lhs instanceof ObjectLike) {\n            lhs = toPrimitive(lhs, \"default\", context);\n            if (context != null && context.isError()) return UNDEFINED;\n        }\n        if (rhs instanceof ObjectLike) {\n            rhs = toPrimitive(rhs, \"default\", context);\n            if (context != null && context.isError()) return UNDEFINED;\n        }\n        if (lhs instanceof String || rhs instanceof String) {\n            return concatOperand(lhs) + concatOperand(rhs);\n        }\n        // BigInt branch — pulled into a fast type test that fails on the common case\n        if (lhs instanceof BigInteger || rhs instanceof BigInteger) {\n            if (!(lhs instanceof BigInteger) || !(rhs instanceof BigInteger)) {\n                throw JsErrorException.typeError(\n                    \"Cannot mix BigInt and other types, use explicit conversions (+)\");\n            }\n            return narrowBigInt(((BigInteger) lhs).add((BigInteger) rhs));\n        }\n        Number lhsNum = objectToNumber(lhs);\n        Number rhsNum = objectToNumber(rhs);\n        double result = lhsNum.doubleValue() + rhsNum.doubleValue();\n        return narrow(result);\n    }\n\n    private static String concatOperand(Object o) {\n        if (o instanceof String s) return s;\n        if (o instanceof Number n) return numberToString(n);\n        return String.valueOf(o);\n    }\n\n    // BigInt does NOT participate in `narrow` (which collapses to int/long/double).\n    // Returning the BigInteger as-is preserves the bigint type identity through","sourceCodeStart":817,"sourceCodeEnd":853,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/Terms.java#L817-L853","documentation":"JS forbids using `+` (or the other arithmetic operators) between a BigInt and any other type, including numbers and strings-as-numbers. Terms.java's add operator detects a mixed BigInt operand pair and throws this TypeError, exactly like V8.","triggerScenarios":"Evaluating `1n + 1`, `1n + '2'`, or any `a + b` in karate-js where exactly one operand is a BigInteger.","commonSituations":"Mixing values that came from BigInt literals with values parsed from JSON/numbers (JSON never produces BigInt), or string concatenation where one side is BigInt from a helper.","solutions":["Convert explicitly on the JS side: use Number(x) or BigInt(x) so both operands match","Use BigInt for both operands if precision matters: 1n + BigInt(jsonValue)","If the intent is string concat, convert with String(bigintValue) + otherString"],"exampleFix":"// before\nvar sum = countN + delta;\n// after\nvar sum = countN + BigInt(delta); // or Number(countN) + delta","handlingStrategy":"type-guard","validationCode":"if ((typeof a === 'bigint') !== (typeof b === 'bigint')) throw new Error('mixed BigInt/non-BigInt operands');","typeGuard":"function bothBigInt(a, b) { return typeof a === 'bigint' && typeof b === 'bigint'; }","tryCatchPattern":"try { sum = a + b; } catch (e) { if (String(e).includes('Cannot mix BigInt')) sum = Number(a) + Number(b); else throw e; }","preventionTips":["Normalize operands with BigInt()/Number() before arithmetic","Remember JSON data never yields BigInt — convert at ingestion","Use explicit String(x) when concatenation, not +, is intended"],"tags":["javascript","bigint","type-error"],"backgroundTag":"type-mismatch","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"}