{"record":{"id":"0f217019329794f2","repo":"apache/seatunnel","slug":"all-candidate-sink-tables-were-skipped-in-spark-st","errorCode":null,"errorMessage":"All candidate sink tables were skipped in Spark starter.","messagePattern":"All candidate sink tables were skipped in Spark starter\\.","errorType":"exception","errorClass":"TaskExecuteException","httpStatus":null,"severity":"error","filePath":"seatunnel-core/seatunnel-spark-starter/seatunnel-spark-2-starter/src/main/java/org/apache/seatunnel/core/starter/spark/execution/SinkExecuteProcessor.java","lineNumber":203,"sourceCode":"                            MultiTableFailureHelper.withFailedTables(\n                                    MultiTableFailureHelper.mergeOptions(\n                                            ReadonlyConfig.fromConfig(sinkConfig),\n                                            ReadonlyConfig.fromConfig(\n                                                    sparkRuntimeEnvironment.getConfig())),\n                                    currentSkippedTables),\n                            classLoader);\n            createdAnySink = true;\n            String applicationId =\n                    sparkRuntimeEnvironment.getSparkSession().sparkContext().applicationId();\n            CatalogTable[] catalogTables =\n                    datasetTableInfo.getCatalogTables().toArray(new CatalogTable[0]);\n            SparkSinkInjector.inject(\n                            dataset.write(), sink, catalogTables, applicationId, parallelism)\n                    .option(\"checkpointLocation\", \"/tmp\")\n                    .save();\n        }\n        if (!createdAnySink && !skippedTables.isEmpty()) {\n            throw new TaskExecuteException(\n                    MultiTableFailureHelper.formatFailedTableSummary(\n                            \"All candidate sink tables were skipped in Spark starter.\",\n                            skippedTables));\n        }\n        if (createdAnySink && !skippedTables.isEmpty()) {\n            log.warn(\n                    MultiTableFailureHelper.formatFailedTableSummary(\n                            \"Some sink tables were skipped in Spark starter.\", skippedTables));\n        }\n        // the sink is the last stream\n        return null;\n    }\n\n    public void handleSaveMode(SeaTunnelSink sink) {\n        if (sink instanceof SupportSaveMode) {\n            Optional<SaveModeHandler> saveModeHandler =\n                    ((SupportSaveMode) sink).getSaveModeHandler();\n            if (saveModeHandler.isPresent()) {","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-core/seatunnel-spark-starter/seatunnel-spark-2-starter/src/main/java/org/apache/seatunnel/core/starter/spark/execution/SinkExecuteProcessor.java#L185-L221","documentation":"SinkExecuteProcessor.execute iterates candidate sink tables, injecting Spark writes; if some tables were skipped (unsupported save mode, inaccessible target, etc.) and none were actually written, it throws a TaskExecuteException with a MultiTableFailureHelper summary of the skipped tables.","triggerScenarios":"All target tables in a multi-table sink run were skipped instead of written — e.g. auto-create/save-mode rules excluded every table, or the sink connector could not handle any of the catalog tables.","commonSituations":"Save mode options (schema_save_mode/data_save_mode) set to values that skip existing tables; target database/table permissions missing; multi-table jobs where table name routing filters exclude everything.","solutions":["Review the skippedTables summary in the exception for per-table reasons","Adjust schema_save_mode/data_save_mode so target tables are written rather than skipped","Verify credentials and permissions on the target catalog/database","Check plugin_input routing/filtering so at least one table is actually matched"],"exampleFix":"// before\nsink {\n  Jdbc {\n    schema_save_mode = \"IGNORE\"\n    data_save_mode = \"IGNORE\"\n  }\n}\n// after\nsink {\n  Jdbc {\n    schema_save_mode = \"CREATE_SCHEMA_WHEN_NOT_EXIST\"\n    data_save_mode = \"APPEND_DATA\"\n  }\n}","handlingStrategy":"validation","validationCode":"if (skippedTables.size() == candidateTables.size()) {\n    throw new IllegalStateException(\"All sink tables would be skipped; check save-mode and routing config\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    sinkProcessor.execute();\n} catch (TaskExecuteException e) {\n    log.error(\"Skipped tables summary: {}\", e.getMessage());\n}","preventionTips":["Set schema_save_mode/data_save_mode to values that actually write (e.g. APPEND_DATA)","Verify sink credentials and target table permissions up front","Audit plugin_input routing so candidate tables aren't all filtered out"],"tags":["spark","sink","multi-table","save-mode"],"backgroundTag":"invalid-config-value","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}