{"record":{"id":"286e306cee2fe737","repo":"apache/pulsar","slug":"the-log-error-handler-cannot-be-set-to-null","errorCode":null,"errorMessage":"The log error handler cannot be set to null","messagePattern":"The log error handler cannot be set to null","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/instance/LogAppender.java","lineNumber":92,"sourceCode":"    @Override\n    public Layout<? extends Serializable> getLayout() {\n        return null;\n    }\n\n    @Override\n    public boolean ignoreExceptions() {\n        return false;\n    }\n\n    @Override\n    public ErrorHandler getHandler() {\n        return errorHandler;\n    }\n\n    @Override\n    public void setHandler(ErrorHandler errorHandler) {\n        if (errorHandler == null) {\n            throw new RuntimeException(\"The log error handler cannot be set to null\");\n        }\n        if (isStarted()) {\n            throw new RuntimeException(\"The log error handler cannot be changed once the appender is started\");\n        }\n        this.errorHandler = errorHandler;\n    }\n\n    @Override\n    public State getState() {\n        return state;\n    }\n\n    @Override\n    public void initialize() {\n        this.state = State.INITIALIZED;\n    }\n\n    @Override","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/instance/LogAppender.java#L74-L110","documentation":"LogAppender.setHandler is called by the function runtime to attach the ErrorHandler that receives log appender failures. Passing null is invalid because the appender relies on the handler to surface producer errors, so the method rejects null with RuntimeException immediately.","triggerScenarios":"Calling setHandler(null) directly on a LogAppender from custom code or a misconfigured appenders setup path that forgot to construct the ErrorHandler.","commonSituations":"Custom function runtime harness code that wires LogAppender manually and passes null when no error handler is defined; framework wiring bug after refactor where the ErrorHandler bean is absent.","solutions":["Always construct and pass a valid org.apache.pulsar.functions.instance.ErrorHandler before calling setHandler","If no failure handling is needed, provide a no-op ErrorHandler implementation rather than null","Call setHandler before start(), since start also requires the handler-dependent wiring to be complete"],"exampleFix":"// before\nlogAppender.setHandler(null);\n// after\nErrorHandler handler = (throwable) -> { log.error(\"log appender failed\", throwable); };\nlogAppender.setHandler(handler);","handlingStrategy":"validation","validationCode":"if (handler == null) {\n    throw new IllegalArgumentException(\"ErrorHandler must be non-null before setHandler\");\n}\nlogAppender.setHandler(handler);","typeGuard":"boolean hasHandler(ErrorHandler h) { return h != null; }","tryCatchPattern":"try { logAppender.setHandler(handler); }\ncatch (RuntimeException e) {\n  if (e.getMessage().contains(\"cannot be set to null\")) {\n    log.error(\"Provide a non-null ErrorHandler\", e);\n  }\n}","preventionTips":["Construct the ErrorHandler before wiring the LogAppender","Provide a no-op ErrorHandler instead of null when handling is unnecessary","Add a null assertion in harness code that wires appenders"],"tags":["java","pulsar-functions","logging","appender","null-check"],"backgroundTag":"null-required-argument","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}