{"record":{"id":"3d050bca85985c09","repo":"apache/seatunnel","slug":"the-value-of-the-s-option-of-the-s-and-s-pl","errorCode":null,"errorMessage":"The value of the '%s' option of the (%s and %s) plugins is both '%s', and they must be different.","messagePattern":"The value of the '(.+?)' option of the \\((.+?) and (.+?)\\) plugins is both '(.+?)', and they must be different\\.","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":182,"sourceCode":"        Map<String, Tuple2<Config, VertexStatus>> vertexStatusMap = new HashMap<>();\n        fillVirtualVertices(sources, vertexStatusMap);\n        fillVirtualVertices(transforms, vertexStatusMap);\n        log.debug(\"Phase 4: Check if a non-existent vertex is used.\");\n        checkInputId(transforms, vertexStatusMap);\n        checkInputId(sinks, vertexStatusMap);\n        log.debug(\"Phase 5: Check if there are unused vertex.\");\n        checkLinked(vertexStatusMap);\n    }\n\n    private static void fillVirtualVertices(\n            List<? extends Config> configs,\n            Map<String, Tuple2<Config, VertexStatus>> vertexStatusMap) {\n        for (Config config : configs) {\n            vertexStatusMap.compute(\n                    ReadonlyConfig.fromConfig(config).get(PLUGIN_OUTPUT),\n                    (id, old) -> {\n                        if (old != null) {\n                            throw new JobDefineCheckException(\n                                    String.format(\n                                            \"The value of the '%s' option of the (%s and %s) plugins is both '%s', and they must be different.\",\n                                            PLUGIN_OUTPUT.key(),\n                                            config.getString(PLUGIN_NAME.key()),\n                                            old._1().getString(PLUGIN_NAME.key()),\n                                            id));\n                        }\n                        return new Tuple2<>(config, VertexStatus.CREATED);\n                    });\n        }\n    }\n\n    private static void checkInputId(\n            List<? extends Config> configs,\n            Map<String, Tuple2<Config, VertexStatus>> vertexStatusMap) {\n        for (Config config : configs) {\n            List<String> inputIds = getInputIds(ReadonlyConfig.fromConfig(config));\n            inputIds.forEach(","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-engine/seatunnel-engine-core/src/main/java/org/apache/seatunnel/engine/core/parse/ConfigParserUtil.java#L164-L200","documentation":"When building a complex multi-table DAG, fillVirtualVertices registers each plugin under its plugin_output table id. If two plugins declare the same plugin_output value, the map compute detects the collision and throws JobDefineCheckException. Each table id produced via result_table_name/plugin_output must be unique.","triggerScenarios":"Two source or transform plugins in one job config set the same plugin_output (or result_table_name) value; checked via checkComplexGraph during job parsing.","commonSituations":"Copy-pasting a source block and forgetting to rename result_table_name; two parallel branches both writing to the same intermediate table name; template-generated configs with duplicate ids.","solutions":["Rename the plugin_output value of one of the conflicting plugins so every table id is unique","Check the error message: it names both plugin names and the duplicated id","If both branches need the same data, let the second consume the first via plugin_input instead of re-producing it","Search the config for duplicate result_table_name/plugin_output entries"],"exampleFix":"// before\nsource { FakeSource { plugin_output = \"t1\" } }\nsource { Jdbc { plugin_output = \"t1\" } }\n// after\nsource { FakeSource { plugin_output = \"t1\" } }\nsource { Jdbc { plugin_output = \"t2\" } }","handlingStrategy":"validation","validationCode":"Set<String> outputs = new HashSet<>();\nfor (Config c : allPlugins) {\n    if (!outputs.add(c.getString(\"plugin_output\"))) {\n        throw new IllegalArgumentException(\"Duplicate plugin_output: \" + c.getString(\"plugin_output\"));\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    ConfigParserUtil.fillVirtualVertices(...);\n} catch (JobDefineCheckException e) {\n    log.error(\"Duplicate table id in DAG: {}\", e.getMessage());\n    throw e;\n}","preventionTips":["Enforce unique plugin_output ids across all producers","Naming convention per plugin (e.g. <plugin>-<index>)","Review configs after copy-paste edits","Grep config for duplicate result_table_name/plugin_output values"],"tags":["java","job-config","dag","naming-conflict"],"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"}