{"record":{"id":"bbf81c017d45db26","repo":"karatelabs/karate","slug":"errorrunevent-dispatch-failed-continuing","errorCode":null,"errorMessage":"ErrorRunEvent dispatch failed, continuing: {}","messagePattern":"ErrorRunEvent dispatch failed, continuing: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"karate-core/src/main/java/io/karatelabs/core/ScenarioRuntime.java","lineNumber":2095,"sourceCode":"        return info;\n    }\n\n    private void fireErrorEvent(StepResult sr) {\n        Suite suite = featureRuntime == null ? null : featureRuntime.getSuite();\n        if (suite == null) {\n            return;\n        }\n        // @report=false scenarios are designed to keep sensitive content out of\n        // every reporting surface (HTML, JSONL). Skipping the bus fire here is\n        // the cheapest way to honor that contract — the failure still counts,\n        // it just doesn't surface raw error text to listeners.\n        if (reportDisabled) {\n            return;\n        }\n        try {\n            suite.fireEvent(ErrorRunEvent.of(sr.getError(), this));\n        } catch (Throwable t) {\n            logger.warn(\"ErrorRunEvent dispatch failed, continuing: {}\", t.toString());\n        }\n    }\n\n    /**\n     * Tracks whether the {@code onStepFailure} hook explicitly chose a\n     * soft-assert / hard-stop outcome. Last call wins; if neither is called,\n     * {@link #resolve(boolean)} returns the supplied static-config default.\n     */\n    private static final class FailureDecision {\n\n        private Boolean override;\n\n        void proceed() {\n            override = Boolean.TRUE;\n        }\n\n        void stop() {\n            override = Boolean.FALSE;","sourceCodeStart":2077,"sourceCodeEnd":2113,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/core/ScenarioRuntime.java#L2077-L2113","documentation":"After a scenario error, Karate fires an `ErrorRunEvent` to suite listeners (for reporting). If dispatching to any listener throws, this warning is logged and execution continues — a broken listener can never break the run.","triggerScenarios":"A custom `RunListener`/suite event subscriber throws inside its error-event handler when `suite.fireEvent(ErrorRunEvent.of(...))` iterates listeners.","commonSituations":"Custom reporting listeners writing to a dead file handle or DB; third-party CI listeners with bugs; listener code referencing null scenario state.","solutions":["Inspect `t.toString()` to identify which listener threw","Wrap your listener's handler body in its own try/catch","Verify listener resources (files, connections) are still valid at event time","Update or pin the reporting plugin version"],"exampleFix":"// before\npublic void onError(ErrorRunEvent e) { report.append(e.getError().getMessage()); }\n// after\npublic void onError(ErrorRunEvent e) { try { report.append(String.valueOf(e.getError().getMessage())); } catch (Exception ex) { log.warn(\"listener failed\", ex); } }","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// In your RunListener:\npublic void onError(ErrorRunEvent e) { try { handle(e); } catch (Throwable t) { log.warn(\"listener failed\", t); } }","preventionTips":["Make all suite listeners exception-safe internally","Verify listener resources (files, sockets) before writing","Pin/update versions of third-party reporting listeners"],"tags":["karate","events","listeners"],"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"}