{"record":{"id":"6ea3404336b3d6f9","repo":"apache/druid","slug":"emitter-is-null-cannot-emit","errorCode":null,"errorMessage":"Emitter is null, cannot emit.","messagePattern":"Emitter is null, cannot emit\\.","errorType":"error_code","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/java/util/emitter/service/AlertBuilder.java","lineNumber":107,"sourceCode":"    return this;\n  }\n\n  public AlertBuilder severity(AlertEvent.Severity severity)\n  {\n    this.severity = severity;\n    return this;\n  }\n\n  @Override\n  public AlertEvent build(ImmutableMap<String, String> serviceDimensions)\n  {\n    return new AlertEvent(DateTimes.nowUtc(), serviceDimensions, severity, description, dataMap);\n  }\n\n  public void emit()\n  {\n    if (emitter == null) {\n      throw new UnsupportedOperationException(\"Emitter is null, cannot emit.\");\n    }\n\n    emitter.emit(this);\n  }\n}\n","sourceCodeStart":89,"sourceCodeEnd":113,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/java/util/emitter/service/AlertBuilder.java#L89-L113","documentation":"AlertBuilder wraps an alert event and a reference to an Emitter. If the builder was constructed without an Emitter (the null-emitter constructor), emit() throws UnsupportedOperationException instead of silently dropping the alert. It is a programmatic misuse guard: alerts must be wired to an emitter before they can be sent.","triggerScenarios":"Calling new AlertBuilder(description).ok()/warn()/critical() via the constructor variant that takes no Emitter (or passing null), then calling .emit(). Seen in code paths like handleAuthorizationCheckError where the emitter dependency was not injected.","commonSituations":"Unit tests instantiating AlertBuilder without an emitter; framework/extension code where the Emitter is not yet initialized (e.g. alert emitted before Druid startup wiring completes) or a DI/config oversight left emitter null.","solutions":["Construct the AlertBuilder with a real emitter: new AlertBuilder(emitter, description) or set the emitter before emit().","Ensure the Druid emitter module is initialized before any component can emit alerts (check startup order / lifecycle wiring).","If emitting alerts from a context without an emitter (e.g. tests), stub the emitter with a no-op Emitter implementation instead of passing null.","Guard call sites: only call emit() when an emitter is configured, otherwise log the alert."],"exampleFix":"// before\nAlertBuilder alert = new AlertBuilder(\"Auth check failed\").severity(Alert.Severity.NOTIFICATION);\nalert.emit(); // UnsupportedOperationException: emitter is null\n// after\nAlertBuilder alert = new AlertBuilder(emitter, \"Auth check failed\").severity(Alert.Severity.NOTIFICATION);\nif (emitter != null) {\n  alert.emit();\n} else {\n  log.warn(\"No emitter configured; dropping alert\");\n}","handlingStrategy":"type-guard","validationCode":"if (emitter == null) { log.warn(\"No emitter configured; skipping alert\"); return; }","typeGuard":"boolean canEmit = (emitter != null);","tryCatchPattern":"try {\n  alert.emit();\n} catch (UnsupportedOperationException e) {\n  log.warn(\"Alert dropped: no emitter configured\");\n}","preventionTips":["Always construct AlertBuilder with the emitter-taking constructor in production code","Verify lifecycle wiring: emitter must be initialized before components emit alerts","In tests, inject a no-op/capturing Emitter rather than null"],"tags":["emitter","null","alert","misuse"],"backgroundTag":"unsupported-operation","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}