{"record":{"id":"655bfd5131a58aae","repo":"karatelabs/karate","slug":"hook-failed-scenarioruntime","errorCode":null,"errorMessage":"{} hook failed: {}","messagePattern":"(.+?) hook failed: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"karate-core/src/main/java/io/karatelabs/core/ScenarioRuntime.java","lineNumber":2252,"sourceCode":"            channels = new ArrayList<>();\n        }\n        channels.add(channel);\n    }\n\n    /**\n     * Invoke a lifecycle hook (beforeScenario / afterScenario) if it is a callable.\n     * Returns null on success or no-op; returns the Throwable on failure.\n     * Exceptions are always logged WARN (callers decide whether to surface as a scenario failure).\n     */\n    private Throwable invokeHook(Object hookRef, String hookName) {\n        if (!(hookRef instanceof JavaCallable callable)) {\n            return null;\n        }\n        try {\n            callable.call(null);\n            return null;\n        } catch (Exception e) {\n            logger.warn(\"{} hook failed: {}\", hookName, e.getMessage());\n            return e;\n        }\n    }\n\n    /**\n     * Run a lifecycle hook and append a synthetic StepResult describing the invocation\n     * to the scenario's step list so it renders in the HTML report alongside regular\n     * Gherkin steps. The synthetic step carries any karate.call() results produced inside\n     * the hook (via the same buffer real steps use) plus the hook's log / embed output.\n     * Returns null when there is no callable hook configured or the hook passed; returns\n     * the Throwable so callers can apply the existing stop/continue semantics.\n     */\n    private Throwable invokeAndRecordHook(Object hookRef, String hookName) {\n        if (!(hookRef instanceof JavaCallable)) {\n            return null;\n        }\n        long startTime = System.currentTimeMillis();\n        long startNanos = System.nanoTime();","sourceCodeStart":2234,"sourceCodeEnd":2270,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/core/ScenarioRuntime.java#L2234-L2270","documentation":"Karate runs lifecycle hooks (e.g. scenario setup/teardown callables) and, if a hook throws an Exception, logs this warning with the hook name and message and returns the exception to the caller instead of propagating it. The scenario continues unless the caller decides otherwise.","triggerScenarios":"Any registered lifecycle hook callable (`callable.call(null)`) throws — e.g. a `configure userDefinedHook` / `afterScenario` style hook whose JS or Java lambda raises.","commonSituations":"Hooks calling karate features that fail; null dereferences on missing config values; environment teardown scripts that error (DB cleanup, API calls).","solutions":["Read the hookName and message in the log to locate the failing hook","Null-check any config/variables the hook reads","Wrap risky parts of the hook body in try/catch inside the hook itself","Run the hook's logic as a normal feature first to reproduce the error"],"exampleFix":"// before\nconfigure afterScenario = function(){ karate.call('classpath:cleanup.feature') }\n// after\nconfigure afterScenario = function(){ try { karate.call('classpath:cleanup.feature') } catch(e){ karate.log('cleanup failed', e) } }","handlingStrategy":"try-catch","validationCode":"// Validate hook dependencies at config time:\nif (!karate.get('cleanupUrl')) { throw new Error('cleanupUrl missing; hook would fail'); }","typeGuard":null,"tryCatchPattern":"try { callable.call(null); } catch (Exception e) { logger.warn(\"{} hook failed: {}\", hookName, e.getMessage()); }","preventionTips":["Keep hooks small and defensive","Null-check config values hooks depend on","Log and swallow inside the hook for non-critical cleanup"],"tags":["karate","hooks","lifecycle"],"backgroundTag":"hook-execution-failed","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"}