{"record":{"id":"8f3a30a3ff78c726","repo":"apache/seatunnel","slug":"multitablewriterrunnable-can-t-find-writer-for-tab","errorCode":null,"errorMessage":"MultiTableWriterRunnable can't find writer for tableId: ","messagePattern":"MultiTableWriterRunnable can't find writer for tableId: ","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"seatunnel-api/src/main/java/org/apache/seatunnel/api/sink/multitablesink/MultiTableWriterRunnable.java","lineNumber":199,"sourceCode":"     */\n    void writeRow(SeaTunnelRow row) throws Throwable {\n        if (row.getArity() == 0) {\n            log.debug(\n                    \"Skip control SeaTunnelRow with zero arity in MultiTableWriterRunnable: {}\",\n                    row);\n            return;\n        }\n        SinkWriter<SeaTunnelRow, ?, ?> writer = tableIdWriterMap.get(row.getTableId());\n        if (writer == null) {\n            if (allowSingleWriterFallback && tableIdWriterMap.size() == 1) {\n                writer = tableIdWriterMap.values().stream().findFirst().get();\n                currentTableId = tableIdWriterMap.keySet().stream().findFirst().get();\n            } else if (continueOnTableFailure) {\n                log.debug(\"Skip row for quarantined table {}\", row.getTableId());\n                return;\n            } else {\n                currentTableId = row.getTableId();\n                throw new RuntimeException(\n                        \"MultiTableWriterRunnable can't find writer for tableId: \"\n                                + row.getTableId());\n            }\n        } else {\n            currentTableId = row.getTableId();\n        }\n        try {\n            beginCollectedRowErrorOutcomeProbe(row);\n            writeWithRetry(writer, row, currentTableId);\n            if (!consumeCollectedRowErrorOutcome(row)) {\n                writeSuccessHandler.accept(row);\n            }\n        } catch (InterruptedException interruptedException) {\n            clearCollectedRowErrorOutcomeProbe(row);\n            throw interruptedException;\n        } catch (Throwable error) {\n            clearCollectedRowErrorOutcomeProbe(row);\n            try {","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-api/src/main/java/org/apache/seatunnel/api/sink/multitablesink/MultiTableWriterRunnable.java#L181-L217","documentation":"Thrown by MultiTableWriterRunnable.writeRow when an incoming SeaTunnelRow's tableId has no matching writer in the tableIdWriterMap. The multi-table sink dispatches rows to per-table writers; a row whose table id was never registered (or whose writer was quarantined/failed) cannot be routed, so the runnable fails the record deliberately.","triggerScenarios":"A row arrives whose TableId is not a key of tableIdWriterMap: the upstream source emitted a tableId the sink never created a writer for, writer creation for that table failed earlier, or writers were removed after a table error without continueOnTableFailure enabled.","commonSituations":"Multi-table (whole-database) synchronization where the source discovers a new table at runtime that the sink's writer map does not cover; schema/table list changed between split enumeration and writing; upstream connector bug emitting mismatched table ids.","solutions":["Verify the source's produced CatalogTables/TableIds match the sink's configured table list","Re-run the job after fixing upstream table discovery so sink writers are created for every source table","Enable continue-on-failure options only if intentionally quarantining failing tables, and check earlier ERROR logs for writer-creation failures","Upgrade/patch connectors if a connector emits table ids inconsistent with its catalog tables"],"exampleFix":"// before\nrow with tableId \"db.new_table\" arrives; sink has writers only for db.table1, db.table2 -> RuntimeException\n// after\nensure source table list and sink table config both include db.new_table before submitting the job","handlingStrategy":"validation","validationCode":"if (!tableIdWriterMap.containsKey(row.getTableId())) { log.warn(\"No writer for tableId {}\", row.getTableId()); return; }","typeGuard":"boolean hasWriter = tableIdWriterMap.containsKey(row.getTableId());","tryCatchPattern":"try { runnable.writeRow(row); } catch (RuntimeException e) { /* inspect tableId vs writer map */ }","preventionTips":["Keep sink table config and source table list in sync","Log and reconcile writer map contents at job start","Enable continue-on-failure only deliberately"],"tags":["sink","multi-table","table-routing"],"backgroundTag":"resource-not-found","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"}