{"record":{"id":"287064c8c8060e3b","repo":"karatelabs/karate","slug":"js-error-error","errorCode":null,"errorMessage":"JS error: {error}","messagePattern":"JS error: (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"karate-core/src/main/java/io/karatelabs/driver/cdp/CdpDriver.java","lineNumber":2013,"sourceCode":"        // For OOPIFs, cdp.sessionId is routed to the iframe's own CDP session. Each session\n        // has its own \"default\" execution context, which IS the OOPIF's main world. Passing\n        // a contextId from frameContexts (registered against a different session) would yield\n        // \"Cannot find context with specified id\". Returning null lets CDP pick the default.\n        if (oopifSessions.containsKey(currentFrame.id)) {\n            return null;\n        }\n        return frameContexts.get(currentFrame.id);\n    }\n\n    private Object extractJsValue(CdpResponse response, String expression) {\n        if (response.isError()) {\n            String message = response.getErrorMessage();\n            if (message != null && message.contains(\"Object reference chain is too long\")) {\n                logger.debug(\"script result not serializable, returning null: {}\", truncate(expression, 100));\n                return null;\n            }\n            logger.warn(\"JS error for expression: {}\", truncate(expression, 100));\n            throw new RuntimeException(\"JS error: \" + response.getError());\n        }\n        Object exceptionDetails = response.getResult(\"exceptionDetails\");\n        if (exceptionDetails != null) {\n            // Try to get detailed error message from exception object\n            String description = response.getResultAsString(\"exceptionDetails.exception.description\");\n            if (description != null && !description.isEmpty()) {\n                logger.warn(\"JS exception for: {} -> {}\", truncate(expression, 100), truncate(description, 200));\n                throw new RuntimeException(\"JS exception: \" + description);\n            }\n            // Fall back to text (usually just \"Uncaught\")\n            String text = response.getResultAsString(\"exceptionDetails.text\");\n            logger.warn(\"JS exception for: {} -> {}\", truncate(expression, 100), text);\n            throw new RuntimeException(\"JS exception: \" + text);\n        }\n        Object value = response.getResult(\"result.value\");\n        logger.trace(\"script result: {}\", value);\n        return value;\n    }","sourceCodeStart":1995,"sourceCodeEnd":2031,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/driver/cdp/CdpDriver.java#L1995-L2031","documentation":"A Runtime.evaluate call returned an error response (not an exception in page JS, but a CDP-level error such as an unserializable result or an internal evaluation failure). Karate logs a warning with a truncated expression and rethrows 'JS error: <error>'. 'Object reference chain is too long' is special-cased and returns null instead.","triggerScenarios":"driver.script(expression) where the CDP response carries errorMessage — deep/deeply-nested return values the protocol cannot serialize, evaluating on a torn-down execution context reported as an error, or browser refusing the evaluate request.","commonSituations":"Scripts returning DOM nodes or huge object graphs; evaluating on a stale context right after navigation; calling script() while the page is mid-navigation; expressions referencing objects Chrome cannot remote-object serialize.","solutions":["Return primitive/JSON-friendly values from your JS expression (map to plain objects/strings instead of DOM nodes)","Wrap the expression in JSON.stringify(...) so the result is a plain string","Retry the script call shortly after navigation to let Chrome recreate the execution context","If it persists, upgrade Karate/browser — some CDP serialization quirks are version-specific"],"exampleFix":"// before\nObject huge = driver.script(\"document.querySelectorAll('a')\"); // JS error\n// after\nString json = (String) driver.script(\"JSON.stringify(Array.from(document.querySelectorAll('a')).map(a => a.href))\");","handlingStrategy":"try-catch","validationCode":"// keep evaluate results serializable by design: return strings/numbers/plain objects\nString safeExpr = \"JSON.stringify((\" + expression + \"))\";","typeGuard":null,"tryCatchPattern":"try { Object v = driver.script(expr); } catch (RuntimeException e) { if (e.getMessage().startsWith(\"JS error:\")) { return null; /* e.g. unserializable */ } throw e; }","preventionTips":["Return primitives or JSON.stringify'd strings from script()","Never return raw DOM nodes or deep native object graphs from expressions","Retry script calls briefly after navigations (context recreation)","Check the errorMessage in logs for protocol-specific serialization limits"],"tags":["cdp","javascript","runtime-evaluate","serialization"],"backgroundTag":"api-error-response","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"}