{"record":{"id":"dcb58fc786c779b4","repo":"apache/seatunnel","slug":"java-io-ioexception","errorCode":null,"errorMessage":"java.io.IOException","messagePattern":"java\\.io\\.IOException","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/task/error/ErrorHandlingSinkWriter.java","lineNumber":219,"sourceCode":"        }\n    }\n\n    private void flushErrorHandler() throws IOException {\n        flushErrorHandler(null);\n    }\n\n    private void flushErrorHandler(Long checkpointId) throws IOException {\n        if (errorHandler == null) {\n            return;\n        }\n        try {\n            if (checkpointId == null) {\n                errorHandler.flush();\n            } else {\n                errorHandler.flush(checkpointId);\n            }\n        } catch (Exception e) {\n            throw toIOException(e);\n        }\n    }\n\n    private IOException toIOException(Exception e) {\n        if (e instanceof IOException) {\n            return (IOException) e;\n        }\n        return new IOException(e);\n    }\n}\n","sourceCodeStart":201,"sourceCodeEnd":230,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/task/error/ErrorHandlingSinkWriter.java#L201-L230","documentation":"ErrorHandlingSinkWriter.flushErrorHandler wraps any exception thrown by the configured ErrorHandler during flush() in a java.io.IOException and rethrows it (ErrorHandlingSinkWriter.java:208-221, wrapped at 219). A non-IOException failure from the error-handling sink (e.g. the error data writer failing) is converted via toIOException(Exception) which nests the cause. Callers are snapshotState(long) and flushErrorHandler, i.e. this surfaces during checkpoint snapshotting or explicit flush.","triggerScenarios":"errorHandler.flush(checkpointId) or errorHandler.flush() throws (e.g. the error sink cannot write failed rows to its target), and the exception is not already an IOException, so line 219 wraps it in IOException; triggered from snapshotState(checkpointId) during checkpoint or from the no-checkpointId flush path.","commonSituations":"Error-output sink (error table/file) unavailable or misconfigured while the main sink's error handler tries to persist bad rows; permission or connectivity problems on the error-data store; an unchecked exception (NPE, class cast) inside a custom ErrorHandler implementation surfaced as IOException at checkpoint time.","solutions":["Inspect the IOException's cause chain (getCause()) - the real failure from the ErrorHandler is nested there.","Verify the error-handling sink target is reachable, writable, and correctly configured (error table/file path, credentials).","Fix or wrap exceptions correctly in custom ErrorHandler implementations; throwing IOException directly preserves the original error.","Re-run the checkpoint after the error sink recovers; the failing rows are retried from checkpoint state.","Test the error sink write path independently before running the pipeline to catch config problems early."],"exampleFix":"// before: swallowing diagnostic detail\n} catch (Exception e) {\n    throw new IOException(\"flush failed\");\n}\n// after: wrap the real cause so callers can diagnose\n} catch (Exception e) {\n    throw new IOException(\"ErrorHandler flush failed for checkpoint \" + checkpointId, e);\n}","handlingStrategy":"try-catch","validationCode":"// before running the pipeline, verify the error sink target is writable\ntry (Writer w = new OutputStreamWriter(new FileOutputStream(errorSinkPath, true), UTF_8)) {\n    w.write(\"healthcheck\\n\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    sinkWriter.snapshotState(checkpointId);\n} catch (IOException e) {\n    Throwable root = e;\n    while (root.getCause() != null) root = root.getCause();\n    log.error(\"ErrorHandler flush failed during checkpoint {}; root cause: {}\",\n              checkpointId, root.getMessage(), e);\n    throw e; // let the checkpoint fail and retry after the error sink recovers\n}","preventionTips":["Always read the full cause chain of IOExceptions from sink writers - the real error is nested","Keep the error-data sink (error table/file) healthy: monitor disk space, permissions, connectivity","Throw IOException directly from custom ErrorHandler code to avoid lossy wrapping","Test the error-handling write path with sample bad rows before production runs","Rely on checkpoint retry to redeliver failed rows once the error sink is fixed"],"tags":["io","sink","error-handler","checkpoint"],"backgroundTag":"file-write-failed","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}