{"record":{"id":"5d705d76eab4794a","repo":"karatelabs/karate","slug":"karate-fail-called","errorCode":null,"errorMessage":"karate.fail() called","messagePattern":"karate\\.fail\\(\\) called","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"karate-core/src/main/java/io/karatelabs/core/KarateJsUtils.java","lineNumber":992,"sourceCode":"                throw new RuntimeException(\"xmlPath() first argument must be XML node or string, but was: \" + (xmlObj == null ? \"null\" : xmlObj.getClass()));\n            }\n            try {\n                return evalXmlPath(doc, path);\n            } catch (Exception e) {\n                throw new RuntimeException(\"xmlPath failed for path: \" + path + \" - \" + e.getMessage(), e);\n            }\n        };\n    }\n\n    // ========== Control Flow Utilities ==========\n\n    /**\n     * karate.fail(message) - Explicitly fail the scenario with a message.\n     */\n    static JavaInvokable fail() {\n        return args -> {\n            String message = args.length > 0 && args[0] != null ? args[0].toString() : \"karate.fail() called\";\n            throw new RuntimeException(message);\n        };\n    }\n\n    // ========== Type Conversion Utilities (Invokable) ==========\n\n    /**\n     * karate.toJava() - Deprecated no-op for V1 compatibility.\n     * In V2, JavaScript arrays work directly with Java, so this is unnecessary.\n     */\n    static JavaInvokable toJava() {\n        return args -> {\n            logger.warn(\"karate.toJava() is deprecated and a no-op in V2 - JavaScript arrays work directly with Java\");\n            if (args.length < 1) {\n                return null;\n            }\n            return args[0]; // no-op, just return the input\n        };\n    }","sourceCodeStart":974,"sourceCodeEnd":1010,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/core/KarateJsUtils.java#L974-L1010","documentation":"karate.fail(message) is an intentional, explicit failure: it unconditionally throws a RuntimeException with the provided message (or a default) so the current scenario is marked failed. This is not a bug — the script author asked for the scenario to stop and fail.","triggerScenarios":"Any call to karate.fail() or karate.fail('msg') inside a scenario/JS block executes and always throws. Often seen in conditional logic: if (bad) karate.fail('...').","commonSituations":"Guard clauses in feature files for unsupported environments; deliberate failure when preconditions are not met; leftover debug calls accidentally committed.","solutions":["Fix the condition that led to the karate.fail() call being reached","Read the custom message — it describes why the author failed the scenario","Remove or gate the karate.fail() call if it should not fire in this environment"],"exampleFix":"// before\nif (env == 'prod') karate.fail();\n// after\nif (env == 'prod') karate.skip('not runnable in prod');","handlingStrategy":"validation","validationCode":"// JS: gate the fail behind the failing condition and log context\nif (cond) { karate.logger.warn('failing because cond, value={}', value); karate.fail('cond was true, value=' + value); }","typeGuard":null,"tryCatchPattern":"// Not normally caught — karate.fail is meant to fail the scenario.\n// If intercepting (e.g. in a wrapper), rethrow:\ntry { karate.fail('reason'); } finally { /* cleanup */ }","preventionTips":["Prefer karate.skip() over fail() for environment-based exclusions","Always pass a descriptive message to karate.fail()","Search commits for stray debug karate.fail() calls before merging"],"tags":["explicit-failure","scenario","control-flow"],"backgroundTag":"invalid-state-transition","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"}