influxdata/influxdb · error
no duplicate table by ID or name
Error message
no duplicate table by ID or name
What it means
After building a TableTransaction for a newly created table, the code inserts it into self.tables and expects no entry with the same table_id (or name-keyed duplicate) to exist. A hit means the batch already contains a table with this ID or name, violating the one-transaction-per-table invariant for new-table creation paths.
Solutions
- Ensure each table is created at most once per CatalogBatch; deduplicate table creation before building the batch
- Never replay or append to a batch that has already had a table inserted; start a fresh batch on retry
- Confirm table_id generation is unique (no reset/colliding sequence) in any custom batch construction
- If triggered through the normal write API on a current version, report it as a bug
Example fix
// before
batch.create_table("cpu")?;
batch.create_table("cpu")?; // panics on insert: duplicate by ID/name
// after
if !batch.contains_table("cpu") {
batch.create_table("cpu")?;
} Defensive patterns
Strategy: validation
Validate before calling
// dedupe table creations before applying
let mut seen = std::collections::HashSet::new();
for name in &table_names {
if !seen.insert(name.clone()) {
return Err(anyhow!("duplicate table creation for {name} in one batch"));
}
} Type guard
fn is_new_table(batch: &CatalogBatch, id: TableId, name: &str) -> bool {
!batch.tables.keys().any(|k| k.id == id)
&& batch.tables.values().all(|t| t.table.name != name)
} Prevention
- Deduplicate CREATE TABLE requests before batching
- Never append to or replay an already-applied batch
- Ensure table_id generators cannot collide or reset
- Track created tables per batch in application code
When it happens
Trigger: Calling the create-table path (which ends in this insert) with a table_id/name that already has a transaction in the batch — e.g. creating the same table twice in one CatalogBatch, or a table_id collision from a mis-seeded generator.
Common situations: Duplicate CREATE TABLE statements consolidated into a single batch; a batch replayed/appended after partial application; custom tooling reusing table IDs across batches.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- column id in series key should be valid
- Existing transaction for table should not exist
- ordered catalog batch should succeed when applied
- table should exist by id
- attempted to create a resource that already exists
AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19).
Data as JSON: /api/errors/cc995cb92d7a16cf.
Report an issue: GitHub.
Appendix: source
Thrown at influxdb3_catalog/src/catalog/versions/v2/update.rs:2030
self.columns_per_table_limit,
self.storage_mode,
);
if let Some(CreateTableColumns { tags, fields }) = columns {
for tag in tags {
table_tx.add_tag(tag)?;
}
for (field_name, field_type) in fields {
table_tx.add_field(field_name, (*field_type).into())?;
}
table_tx.add_time()?;
}
self.tables
.insert(table_id, table_tx)
.expect("no duplicate table by ID or name");
Ok(table_id)
}
pub fn db_schema(&self) -> &Arc<DatabaseSchema> {
&self.database_schema
}
}
impl From<DatabaseCatalogTransaction> for CatalogBatch {
fn from(txn: DatabaseCatalogTransaction) -> Self {
let mut ops = txn.ops;
let mut tables = txn.tables;
ops.extend(tables.repo.drain(..).filter_map(|(_, tx)| {
if tx.column_definitions.is_empty() && tx.field_family_definitions.is_empty() {
None
} else {
Some(DatabaseCatalogOp::AddColumns(tx.into()))View on GitHub (pinned to 06200ef96b)