{"record":{"id":"49490ebd9deca149","repo":"apache/seatunnel","slug":"duplicate-object","errorCode":"DUPLICATE_OBJECT","errorMessage":"Duplicate object in tables_configs: \" + tableId","messagePattern":"Duplicate object in tables_configs: \" \\+ tableId","errorType":"error_code","errorClass":"SalesforceConnectorException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-salesforce/src/main/java/org/apache/seatunnel/connectors/seatunnel/salesforce/source/SalesforceSource.java","lineNumber":79,"sourceCode":"     * lifetime is scoped to this call (try-with-resources).\n     */\n    private List<SalesforceTableConfig> buildTableConfigs(\n            SalesforceParameters params, ReadonlyConfig config) {\n        try (SalesforceClient client = new SalesforceClient(params)) {\n            client.authenticate();\n\n            if (config.getOptional(ConnectorCommonOptions.TABLE_CONFIGS).isPresent()) {\n                List<Map<String, Object>> tableConfigMaps =\n                        config.get(ConnectorCommonOptions.TABLE_CONFIGS);\n                List<SalesforceTableConfig> configs = new ArrayList<>();\n                for (Map<String, Object> map : tableConfigMaps) {\n                    ReadonlyConfig tableConfig = ReadonlyConfig.fromMap(map);\n                    SalesforceTableConfig built = buildOneTableConfig(tableConfig, client);\n                    String tableId = built.getTableId();\n                    boolean duplicate =\n                            configs.stream().anyMatch(c -> c.getTableId().equals(tableId));\n                    if (duplicate) {\n                        throw new SalesforceConnectorException(\n                                SalesforceConnectorErrorCode.DUPLICATE_OBJECT,\n                                \"Duplicate object in tables_configs: \" + tableId);\n                    }\n                    configs.add(built);\n                }\n                return configs;\n            } else {\n                String objectName = config.get(SalesforceSourceOptions.OBJECT_NAME);\n                String soql = buildSoql(config, objectName);\n                CatalogTable table = client.describeObject(PLUGIN_NAME, objectName);\n                return Collections.singletonList(\n                        new SalesforceTableConfig(soql, objectName, table));\n            }\n        } catch (SalesforceConnectorException e) {\n            throw e;\n        } catch (Exception e) {\n            throw new SalesforceConnectorException(\n                    SalesforceConnectorErrorCode.DESCRIBE_OBJECT_FAILED,","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-salesforce/src/main/java/org/apache/seatunnel/connectors/seatunnel/salesforce/source/SalesforceSource.java#L61-L97","documentation":"Thrown by SalesforceSource.buildTableConfigs while expanding tables_configs entries when two entries resolve to the same tableId (SOQL/object identity). The connector refuses to build duplicate source tables.","triggerScenarios":"Configuring tables_configs with two entries whose table_path (or generated SOQL-derived table id) is identical, or entries that normalize to the same Salesforce object with the same query.","commonSituations":"Copy-pasting a table entry and forgetting to change the object/SOQL; listing the same object twice with slightly different formatting that normalizes to the same id; template-generated configs duplicating a table.","solutions":["Review tables_configs and remove or merge entries with duplicate table_path values","Ensure each entry targets a distinct Salesforce object or uses a distinct SOQL when intentionally splitting a load","Regenerate the config from a template check to avoid duplicated blocks"],"exampleFix":"// before\ntables_configs = [{table_path=\"default.Account\"}, {table_path=\"default.Account\"}]\n// after\ntables_configs = [{table_path=\"default.Account\"}, {table_path=\"default.Contact\"}]","handlingStrategy":"validation","validationCode":"// dedupe check before submitting the job config\nSet<String> seen = new HashSet<>();\nfor (Map<String,Object> t : tablesConfigs) {\n    if (!seen.add((String) t.get(\"table_path\"))) {\n        throw new IllegalArgumentException(\"Duplicate table_path: \" + t.get(\"table_path\"));\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Review tables_configs for copy-paste duplicates before running","Keep a single source of truth for table definitions (template generation with checks)","Remember table_path is the identity — two entries with the same path always collide"],"tags":["config","salesforce","duplicate"],"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-14T11:17:12.474Z"}