{"record":{"id":"164623f476c0b345","repo":"apache/seatunnel","slug":"the-s-option-configured-is-incorrect-this-tabl","errorCode":null,"errorMessage":"The '%s' option configured is incorrect, this table(%s) belonging to source/transform(%s) is not used.","messagePattern":"The '(.+?)' option configured is incorrect, this table\\((.+?)\\) belonging to source/transform\\((.+?)\\) is not used\\.","errorType":"validation","errorClass":"JobDefineCheckException","httpStatus":null,"severity":"error","filePath":"seatunnel-engine/seatunnel-engine-core/src/main/java/org/apache/seatunnel/engine/core/parse/ConfigParserUtil.java","lineNumber":222,"sourceCode":"                                    (id, old) -> {\n                                        if (old == null) {\n                                            throw new JobDefineCheckException(\n                                                    String.format(\n                                                            \"The '%s' option configured in [%s] is incorrect, and the source/transform[%s] is not found.\",\n                                                            PLUGIN_INPUT.key(),\n                                                            config.getString(PLUGIN_NAME.key()),\n                                                            id));\n                                        }\n                                        return new Tuple2<>(old._1(), VertexStatus.LINKED);\n                                    }));\n        }\n    }\n\n    private static void checkLinked(Map<String, Tuple2<Config, VertexStatus>> vertexStatusMap) {\n        vertexStatusMap.forEach(\n                (id, vertex) -> {\n                    if (vertex._2() == VertexStatus.CREATED) {\n                        throw new JobDefineCheckException(\n                                String.format(\n                                        \"The '%s' option configured is incorrect, this table(%s) belonging to source/transform(%s) is not used.\",\n                                        PLUGIN_INPUT.key(),\n                                        id,\n                                        vertex._1().getString(PLUGIN_NAME.key())));\n                    }\n                });\n    }\n\n    private static void checkExistTableId(List<? extends Config> configs) {\n        for (Config config : configs) {\n            if (!ReadonlyConfig.fromConfig(config).getOptional(PLUGIN_OUTPUT).isPresent()) {\n                throw new JobDefineCheckException(\n                        String.format(\n                                \"The source/transform(%s) is not configured with '%s' option\",\n                                config.getString(PLUGIN_NAME.key()), PLUGIN_OUTPUT.key()),\n                        new OptionValidationException(PLUGIN_OUTPUT));\n            }","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-engine/seatunnel-engine-core/src/main/java/org/apache/seatunnel/engine/core/parse/ConfigParserUtil.java#L204-L240","documentation":"checkLinked ensures every source/transform vertex in a complex graph is consumed (its VertexStatus is marked from CREATED). If a vertex's output table id is never referenced by any downstream plugin_input, JobDefineCheckException is thrown saying the table is unused. Every produced table must be linked into the pipeline.","triggerScenarios":"A source/transform declares plugin_output but no downstream transform/sink references that id via plugin_input; detected in checkComplexGraph via checkLinked after all edges are resolved.","commonSituations":"Deleting the downstream sink/transform but leaving the orphan producer; renaming the consumer's plugin_input without updating the producer; intentionally disabled branch still emitting a table id.","solutions":["Add or fix a downstream plugin whose plugin_input references the unused table id","Remove the orphan source/transform block if its output is no longer needed","Match the error's table id to find the unused producer in the config","Verify each plugin_output has at least one matching plugin_input"],"exampleFix":"// before\nsource { FakeSource { plugin_output = \"t1\" } }\nsink { Console { plugin_input = \"t2\" } }\n// after\nsource { FakeSource { plugin_output = \"t1\" } }\nsink { Console { plugin_input = \"t1\" } }","handlingStrategy":"validation","validationCode":"Set<String> consumed = collectPluginInputs(config);\nfor (String out : collectPluginOutputs(config)) {\n    if (!consumed.contains(out)) {\n        throw new IllegalArgumentException(\"Unused table id: \" + out);\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    ConfigParserUtil.checkLinked(...);\n} catch (JobDefineCheckException e) {\n    log.error(\"Unlinked vertex: {}\", e.getMessage());\n    throw e;\n}","preventionTips":["Every plugin_output must have a downstream consumer","Remove orphan producers when deleting branches","Draw the DAG on paper before writing multi-table configs","Validate with checkGraph in CI"],"tags":["java","job-config","dag","unconnected-node"],"backgroundTag":"conflicting-config-options","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T21:17:11.552Z"}