{"record":{"id":"a370c8d4dab955b9","repo":"apache/seatunnel","slug":"all-candidate-sink-tables-were-skipped-in-spark-st-a370c8","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-starter-common/src/main/java/org/apache/seatunnel/core/starter/spark/execution/SinkExecuteProcessor.java","lineNumber":203,"sourceCode":"                                    MultiTableFailureHelper.mergeOptions(\n                                            ReadonlyConfig.fromConfig(sinkConfig),\n                                            ReadonlyConfig.fromConfig(\n                                                    sparkRuntimeEnvironment.getConfig())),\n                                    currentSkippedTables),\n                            classLoader);\n            createdAnySink = true;\n            String applicationId =\n                    sparkRuntimeEnvironment.getStreamingContext().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                    .mode(SaveMode.Append)\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-starter-common/src/main/java/org/apache/seatunnel/core/starter/spark/execution/SinkExecuteProcessor.java#L185-L221","documentation":"In SinkExecuteProcessor.execute, each candidate sink table can be skipped (e.g. by save-mode policies or routing). If every candidate table ended up skipped and no sink was ever written, the processor fails fast with this error plus a formatted summary of why each table was skipped, instead of silently writing nothing.","triggerScenarios":"All tables routed to the sink were skipped (createdAnySink == false) while skippedTables is non-empty — e.g. every table hit a save-mode/skip condition or sink routing matched no writable table.","commonSituations":"Catalog-table routing misconfigured (plugin_input/plugin_output identifiers not matching); SaveMode policies (e.g. 'error_if_exists' filtering logic) skipping all tables; upstream produced zero matching tables so every sink candidate was dropped.","solutions":["Inspect the skippedTables summary in the error to see each table's skip reason","Fix the sink plugin_input/plugin_output routing so at least one table matches","Check the sink's save-mode handler configuration that may be causing tables to be skipped","Log/verify upstream transform output table names match sink expectations"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Ensure sink plugin_input/plugin_output identifiers match upstream table names\nassert sinkConfig.pluginInputs.stream().allMatch(upstreamTables::contains);","typeGuard":null,"tryCatchPattern":"try {\n    runSparkJob();\n} catch (TaskExecuteException e) {\n    if (e.getMessage().contains(\"All candidate sink tables were skipped\")) {\n        log.error(\"Sink routing misconfigured, review skippedTables summary\", e);\n    }\n}","preventionTips":["Verify plugin_input/plugin_output table identifiers match upstream names exactly","Review save-mode settings that may cause tables to be skipped","Check the skippedTables summary included in the error message"],"tags":["spark","sink","multi-table"],"backgroundTag":"empty-result-set","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"}