{"record":{"id":"6f832fc6a81e37ab","repo":"apache/iceberg","slug":"failed-to-notify-listeners","errorCode":null,"errorMessage":"Failed to notify listeners","messagePattern":"Failed to notify listeners","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"core/src/main/java/org/apache/iceberg/SnapshotProducer.java","lineNumber":594,"sourceCode":"        Listeners.notifyAll(event);\n\n        if (event instanceof CreateSnapshotEvent) {\n          CreateSnapshotEvent createSnapshotEvent = (CreateSnapshotEvent) event;\n\n          reporter.report(\n              ImmutableCommitReport.builder()\n                  .tableName(createSnapshotEvent.tableName())\n                  .snapshotId(createSnapshotEvent.snapshotId())\n                  .operation(createSnapshotEvent.operation())\n                  .sequenceNumber(createSnapshotEvent.sequenceNumber())\n                  .metadata(EnvironmentContext.get())\n                  .commitMetrics(\n                      CommitMetricsResult.from(commitMetrics(), createSnapshotEvent.summary()))\n                  .build());\n        }\n      }\n    } catch (RuntimeException e) {\n      LOG.warn(\"Failed to notify listeners\", e);\n    }\n  }\n\n  protected void cleanAll() {\n    for (String manifestList : manifestLists) {\n      deleteFile(manifestList);\n    }\n    manifestLists.clear();\n    cleanUncommitted(EMPTY_SET);\n  }\n\n  protected void deleteFile(String path) {\n    deleteFunc.accept(path);\n  }\n\n  protected OutputFile manifestListPath() {\n    return ops.io()\n        .newOutputFile(","sourceCodeStart":576,"sourceCodeEnd":612,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/SnapshotProducer.java#L576-L612","documentation":"Inside SnapshotProducer.notifyListeners(), any RuntimeException thrown while building or dispatching commit events (including CommitMetricsResult creation) is caught and logged as this warning. It signals that one of the registered listeners failed; the table commit is unaffected. This is a second, inner guard distinct from the outer catch around notifyListeners().","triggerScenarios":"A RuntimeException is thrown by a listener callback or by commitMetrics()/CommitReport construction while notifyListeners() runs after a commit — commonly a listener that throws unchecked exceptions.","commonSituations":"Listeners calling external reporting endpoints that fail; listeners written against an older event API; unhandled NPEs in custom listener code when summary fields are absent.","solutions":["Read the logged exception to identify the failing listener.","Fix the listener so its callbacks never throw RuntimeException.","Add defensive error handling inside the listener around external calls.","Verify listener code matches the current Iceberg event/report API version."],"exampleFix":"// before\npublic void notify(Event event) { report(buildReport(event)); } // unchecked failure surfaces as warning\n// after\npublic void notify(Event event) {\n  try { report(buildReport(event)); } catch (RuntimeException e) { LOG.warn(\"listener failed\", e); }\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  listener.notify(event);\n} catch (RuntimeException e) {\n  LOG.warn(\"listener {} failed; commit unaffected\", listenerName, e);\n}","preventionTips":["Wrap listener bodies in try/catch so they never throw","Keep external reporting calls in listeners bounded by timeouts","Match listener code to the current Iceberg event API","Log and alert on listener failures without failing commits"],"tags":["listeners","runtime-exception","metrics"],"backgroundTag":"http-request-failed","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}