{"record":{"id":"2c8a4bd646a89f6c","repo":"karatelabs/karate","slug":"hook-failed","errorCode":null,"errorMessage":"{} hook failed: {}","messagePattern":"(.+?) hook failed: (.+?)","errorType":"console","errorClass":null,"httpStatus":500,"severity":"warning","filePath":"karate-core/src/main/java/io/karatelabs/core/MockHandler.java","lineNumber":531,"sourceCode":"        // A hook exception surfaces as HTTP 500 (same convention as beforeScenario / step failures).\n        Exception afterError = invokeMockHook(config.getAfterScenario(), \"afterScenario\");\n        if (afterError != null) {\n            return hookErrorResponse(\"afterScenario\", afterError);\n        }\n\n        // Build response from variables\n        return buildResponse(runtime, engine, request);\n    }\n\n    private Exception invokeMockHook(JavaCallable hook, String hookName) {\n        if (hook == null) {\n            return null;\n        }\n        try {\n            hook.call(null);\n            return null;\n        } catch (Exception e) {\n            logger.warn(\"{} hook failed: {}\", hookName, e.getMessage());\n            return e;\n        }\n    }\n\n    private HttpResponse hookErrorResponse(String hookName, Exception error) {\n        return HttpResponse.error(500, hookName + \" hook failed: \" + error.getMessage());\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    private HttpResponse buildResponse(ScenarioRuntime runtime, Engine engine, HttpRequest request) {\n        HttpResponse response = new HttpResponse();\n\n        // Get response variables from engine\n        Object responseBody = engine.get(\"response\");\n        Object responseStatus = engine.get(\"responseStatus\");\n        Object responseStatusText = engine.get(\"responseStatusText\");\n        Object responseHeaders = engine.get(\"responseHeaders\");\n        Object responseDelay = engine.get(\"responseDelay\");","sourceCodeStart":513,"sourceCodeEnd":549,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/core/MockHandler.java#L513-L549","documentation":"A lifecycle hook (before/after mock request hook) registered on the mock server threw an exception when invoked. Karate catches it, logs a warning, and by default converts it into a 500 response via hookErrorResponse so the mocked endpoint still answers. It indicates a bug or unexpected condition inside user-supplied hook code, not in Karate itself.","triggerScenarios":"A hook object passed to MockHandler (mock before/after hooks) throws when hook.call(null) is executed during request processing, via invokeMockHook called from beforeError/afterError handling.","commonSituations":"Hook script references a variable that does not exist; hook JS/Java code throws NPE; hook depends on request state that is absent for certain HTTP methods; a refactor renamed a variable the hook uses.","solutions":["Read the second '{}' value in the log — e.getMessage() of the hook exception — and fix the bug in the hook code.","Wrap the hook body in defensive null checks / try-catch so it never throws for edge-case requests.","If the hook failure should be tolerated, make the hook catch its own exceptions and return a fallback response.","Check that the hook returns/behaves correctly for all HTTP verbs and paths the mock receives."],"exampleFix":"// before\nfn = function(req){ return { status: req.body.length } }\n// after\nfn = function(req){ if (!req.body) return { status: 400 }; try { return { status: req.body.length } } catch (e) { return { status: 500, message: e.message } } }","handlingStrategy":"try-catch","validationCode":"// ensure hook is a function and deps exist before registering\nif (typeof hookFn !== 'function') throw new Error('hook must be a function');","typeGuard":"function isValidHook(h) { return h && typeof h === 'function'; }","tryCatchPattern":"try { hook.call(null); } catch (e) { logger.warn('hook failed: {}', e.getMessage()); /* tolerate or return 500 via hookErrorResponse */ }","preventionTips":["Write hooks defensively: null-check request fields before use.","Cover hooks with unit tests across all HTTP verbs/paths.","Keep hook logic minimal — delegate to tested functions."],"tags":["mock-server","hooks","javascript"],"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"}