{"record":{"id":"2067776d7db2087e","repo":"karatelabs/karate","slug":"callsingle-failed-path-failuremsg","errorCode":null,"errorMessage":"callSingle failed: <path> - <failureMsg>","messagePattern":"callSingle failed: <path> - <failureMsg>","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"karate-core/src/main/java/io/karatelabs/core/ScenarioRuntime.java","lineNumber":854,"sourceCode":"            );\n            FeatureResult fr = nestedFr.call();\n\n            // Attach the called feature's result so its steps (and HTTP traffic) surface\n            // in the calling scenario's HTML / Cucumber JSON / JUnit report. callSingle\n            // executes exactly once per Suite under a lock — only the \"winning\" scenario\n            // (cache miss) reaches this code, so the call results appear under whichever\n            // scenario's thread actually ran the feature. Done before the failure throw\n            // so a failed callSingle still surfaces its steps in the report.\n            executor.addCallResult(fr);\n\n            // Check if the feature failed\n            if (fr.isFailed()) {\n                String failureMsg = fr.getScenarioResults().stream()\n                        .filter(ScenarioResult::isFailed)\n                        .findFirst()\n                        .map(ScenarioResult::getFailureMessage)\n                        .orElse(\"callSingle feature failed\");\n                throw new RuntimeException(\"callSingle failed: \" + path + \" - \" + failureMsg);\n            }\n\n            if (nestedFr.getLastExecuted() != null) {\n                // Cache only the delta — the variables the called feature actually added or\n                // replaced — not its full binding set. A called feature inherits the caller's\n                // visible variables, so the full set echoes back caller state: Scenario Outline\n                // example-row columns (frozen to row 1 and replayed onto later rows via a\n                // karate.set(...) spread — #2934) and config-level refs like Java.type(...)\n                // (serialized into the disk cache, then deserialized as broken values that\n                // clobber the live ref on a warm run — #2933). Diffed against what the callee\n                // was actually seeded with (isolated scope shallow-copies maps and lists, so\n                // comparing against the caller's own live vars read every inherited map as\n                // \"replaced\" and leaked it back) — the same helper the call keyword uses.\n                return StepExecutor.calleeResult(nestedFr.getLastExecuted());\n            }\n            return new HashMap<>();\n        } else if (content instanceof JavaCallable) {\n            // JavaScript function - invoke it with the arg","sourceCodeStart":836,"sourceCodeEnd":872,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/core/ScenarioRuntime.java#L836-L872","documentation":"When karate.callSingle() invokes a feature and that child FeatureRuntime fails, executeCallSingle collects the first failed ScenarioResult's failure message and throws a RuntimeException 'callSingle failed: <path> - <message>'. This re-throws the underlying feature failure to the caller (and caches the exception for subsequent callSingle invocations of the same path).","triggerScenarios":"karate.callSingle('some.feature') where the called feature has a failing scenario — a failed step, assertion, or setup error. The reported message is the first failed scenario's failure text.","commonSituations":"Shared data-provision features (auth token fetch, seed data) failing due to environment issues; a broken helper feature reused across the suite so every callSingle consumer fails; parallel runs surfacing the cached exception repeatedly.","solutions":["Run the called feature standalone (Runner.path) to see the full failure and fix the root cause shown after the ' - '.","Check environment/config the shared feature depends on (URLs, credentials) — callSingle features often fail before any test logic runs.","Note the exception is cached: fix the feature and restart the suite; retrying within the same run returns the cached failure.","If only JS is needed, prefer a .js file over a feature for callSingle to avoid full scenario execution overhead."],"exampleFix":"// before: auth.feature fails\n* def token = karate.callSingle('classpath:auth.feature').token\n// -> callSingle failed: classpath:auth.feature - http call failed ...\n\n// after: harden the shared feature\n* configure retry = { count: 3, interval: 2000 }\n* def token = karate.call('classpath:auth.feature').token","handlingStrategy":"try-catch","validationCode":"// validate the shared feature in a pre-flight check at suite start:\n// Runner.path(\"classpath:auth.feature\").parallel(1) in a build step before the suite","typeGuard":null,"tryCatchPattern":"try {\n    var token = karate.callSingle('classpath:auth.feature').token;\n} catch (e) {\n    if (String(e).indexOf('callSingle failed') >= 0) {\n        karate.log('shared feature failed; cause: ' + e);\n        throw e; // usually a genuine env/config failure — don't mask\n    }\n    throw e;\n}","preventionTips":["Keep callSingle feature scripts dependency-light (no env surprises)","Add retry/configure timeouts in shared auth/data features","Smoke-test shared features standalone before the full suite","Remember the failure is cached per suite run — restart after fixing the feature"],"tags":["callsingle","feature-failure","caching"],"backgroundTag":"upstream-api-error","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"}