apache/seatunnel · error · SeaTunnelRuntimeException
API-09
API-09
Error message
Handle save mode failed
What it means
SinkExecuteProcessor.handleSaveMode applies schema/data save-mode actions via a SaveModeHandler; any exception inside handler.open() or SaveModeExecuteWrapper.execute() is wrapped in a SeaTunnelRuntimeException with code HANDLE_SAVE_MODE_FAILED (API-09).
Source
Thrown at seatunnel-core/seatunnel-spark-starter/seatunnel-spark-2-starter/src/main/java/org/apache/seatunnel/core/starter/spark/execution/SinkExecuteProcessor.java:226
if (createdAnySink && !skippedTables.isEmpty()) {
log.warn(
MultiTableFailureHelper.formatFailedTableSummary(
"Some sink tables were skipped in Spark starter.", skippedTables));
}
// the sink is the last stream
return null;
}
public void handleSaveMode(SeaTunnelSink sink) {
if (sink instanceof SupportSaveMode) {
Optional<SaveModeHandler> saveModeHandler =
((SupportSaveMode) sink).getSaveModeHandler();
if (saveModeHandler.isPresent()) {
try (SaveModeHandler handler = saveModeHandler.get()) {
handler.open();
new SaveModeExecuteWrapper(handler).execute();
} catch (Exception e) {
throw new SeaTunnelRuntimeException(HANDLE_SAVE_MODE_FAILED, e);
}
}
}
}
private boolean shouldContinueOtherTables() {
return MultiTableFailureHelper.shouldContinueOtherTables(
ReadonlyConfig.fromConfig(sparkRuntimeEnvironment.getConfig()));
}
private RuntimeException wrapThrowable(Throwable error) {
if (error instanceof RuntimeException) {
return (RuntimeException) error;
}
return new RuntimeException(error);
}
private void logSkippedTable(View on GitHub (pinned to cf67b549a7)
Solutions
- Read the wrapped cause for the underlying save-mode failure
- Ensure required drivers are on the classpath (add to env jars)
- Verify credentials/permissions for schema creation or data manipulation on the target
- Test the save-mode handler's target connection independently before running the job
Example fix
// before
env {
jars = []
}
// after
env {
jars = "file:///opt/seatunnel/connectors/mysql-connector-java-8.0.x.jar"
} Defensive patterns
Strategy: try-catch
Validate before calling
try (SaveModeHandler h = handler) {
h.open();
} catch (Exception e) {
precheckFailure(e); // surface driver/connection problems before the job
} Try / catch
try {
sinkProcessor.execute();
} catch (SeaTunnelRuntimeException e) {
if ("API-09".equals(e.getSeaTunnelErrorCode().getCode())) {
log.error("Save mode failed, cause:", e.getCause());
}
} Prevention
- Ensure JDBC drivers are on the classpath via env.jars
- Validate save-mode custom SQL in the target database first
- Check write privileges for auto table creation
- Test target connectivity before running the full job
When it happens
Trigger: Executing save-mode operations (auto-create tables, execute DDL/data in save-mode jar) fails — e.g. driver/credentials issues, DDL errors, connection failure while opening the handler.
Common situations: Missing JDBC driver on the Spark classpath; insufficient privileges to create tables; save-mode custom SQL failing; target database unreachable.
Related errors
- All candidate sink tables were skipped in Spark starter.
- TABLE_QUERY_FAILED
- CONFIG_VALIDATION_FAILED
- API-09
- API-09
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/3c652b6f6abbb48b.
Report an issue: GitHub.