apache/seatunnel · error · IllegalArgumentException
table name: must be unique
Error message
table name: <tableNames> must be unique
What it means
MultipleTableFakeSourceConfig requires every table defined in a multi-table FakeSource config to have a unique fully-qualified table name (tableId.toTablePath()). If duplicates are detected (list size != HashSet size), an IllegalArgumentException listing all table names is thrown during construction.
Solutions
- Rename duplicate table entries so each catalog table has a unique database.table name
- Review the table names listed in the exception to locate the duplicates
- If only one table is needed, collapse to a single-table config without the extra entries
Example fix
# before
tables = [
{ table-name = "db.tbl1" }
{ table-name = "db.tbl1" }
]
# after
tables = [
{ table-name = "db.tbl1" }
{ table-name = "db.tbl2" }
] Defensive patterns
Strategy: validation
Validate before calling
// before building the config
List<String> names = tableConfigs.stream()
.map(c -> c.getString("table-name"))
.collect(Collectors.toList());
if (new HashSet<>(names).size() != names.size()) {
throw new IllegalArgumentException("duplicate table names: " + names);
} Try / catch
try {
new MultipleTableFakeSourceConfig(readonlyConfig);
} catch (IllegalArgumentException e) {
// e.getMessage() lists the table names; rename duplicates and retry
} Prevention
- When generating multi-table configs programmatically, deduplicate on the fully-qualified table path
- After copy-pasting table blocks, always update the table name
- Use database-qualified names to avoid namespace collisions
When it happens
Trigger: A FakeSource config with multiple table entries (e.g. 'tables' list or replicated ReadonlyConfig sections) where two or more entries define the same database.table identifier; triggered in the MultipleTableFakeSourceConfig constructor.
Common situations: Copy-pasting a table block and forgetting to change the table name, generating configs via script that emits duplicate entries, or case/namespace confusion where entries resolve to the same TablePath.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- COMMON_ILLEGAL_ARGUMENT
- tables_configs[ ]: duplicate 'schema.table' value
- All candidate sink tables were skipped during job parsing.
- AmazonDocumentDB option 'uri' must include authentication…
- batch_size must be >= 1, got:
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/9500f70145075847.
Report an issue: GitHub.
Appendix: source
Thrown at seatunnel-connectors-v2/connector-fake/src/main/java/org/apache/seatunnel/connectors/seatunnel/fake/config/MultipleTableFakeSourceConfig.java:54
private static final long serialVersionUID = 1L;
@Getter private List<FakeConfig> fakeConfigs;
public MultipleTableFakeSourceConfig(ReadonlyConfig fakeSourceRootConfig) {
if (fakeSourceRootConfig.getOptional(ConnectorCommonOptions.TABLE_CONFIGS).isPresent()) {
parseFromConfigs(fakeSourceRootConfig);
} else {
parseFromConfig(fakeSourceRootConfig);
}
// validate
if (fakeConfigs.size() > 1) {
List<String> tableNames =
fakeConfigs.stream()
.map(FakeConfig::getCatalogTable)
.map(catalogTable -> catalogTable.getTableId().toTablePath().toString())
.collect(Collectors.toList());
if (CollectionUtils.size(tableNames) != new HashSet<>(tableNames).size()) {
throw new IllegalArgumentException("table name: " + tableNames + " must be unique");
}
}
}
private void parseFromConfigs(ReadonlyConfig readonlyConfig) {
List<ReadonlyConfig> readonlyConfigs =
readonlyConfig.getOptional(ConnectorCommonOptions.TABLE_CONFIGS).get().stream()
.map(ReadonlyConfig::fromMap)
.collect(Collectors.toList());
// Use the config outside if it's not set in sub config
fakeConfigs =
readonlyConfigs.stream()
.map(FakeConfig::buildWithConfig)
.collect(Collectors.toList());
}
private void parseFromConfig(ReadonlyConfig readonlyConfig) {
FakeConfig fakeConfig = FakeConfig.buildWithConfig(readonlyConfig);View on GitHub (pinned to cf67b549a7)