{"record":{"id":"cc995cb92d7a16cf","repo":"influxdata/influxdb","slug":"no-duplicate-table-by-id-or-name","errorCode":null,"errorMessage":"no duplicate table by ID or name","messagePattern":"no duplicate table by ID or name","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"influxdb3_catalog/src/catalog/versions/v2/update.rs","lineNumber":2030,"sourceCode":"            self.columns_per_table_limit,\n            self.storage_mode,\n        );\n\n        if let Some(CreateTableColumns { tags, fields }) = columns {\n            for tag in tags {\n                table_tx.add_tag(tag)?;\n            }\n\n            for (field_name, field_type) in fields {\n                table_tx.add_field(field_name, (*field_type).into())?;\n            }\n\n            table_tx.add_time()?;\n        }\n\n        self.tables\n            .insert(table_id, table_tx)\n            .expect(\"no duplicate table by ID or name\");\n\n        Ok(table_id)\n    }\n\n    pub fn db_schema(&self) -> &Arc<DatabaseSchema> {\n        &self.database_schema\n    }\n}\n\nimpl From<DatabaseCatalogTransaction> for CatalogBatch {\n    fn from(txn: DatabaseCatalogTransaction) -> Self {\n        let mut ops = txn.ops;\n        let mut tables = txn.tables;\n        ops.extend(tables.repo.drain(..).filter_map(|(_, tx)| {\n            if tx.column_definitions.is_empty() && tx.field_family_definitions.is_empty() {\n                None\n            } else {\n                Some(DatabaseCatalogOp::AddColumns(tx.into()))","sourceCodeStart":2012,"sourceCodeEnd":2048,"githubUrl":"https://github.com/influxdata/influxdb/blob/06200ef96ba82c5f6727e5038a83af8e722c6875/influxdb3_catalog/src/catalog/versions/v2/update.rs#L2012-L2048","documentation":"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.","triggerScenarios":"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.","commonSituations":"Duplicate CREATE TABLE statements consolidated into a single batch; a batch replayed/appended after partial application; custom tooling reusing table IDs across batches.","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"],"exampleFix":"// before\nbatch.create_table(\"cpu\")?;\nbatch.create_table(\"cpu\")?; // panics on insert: duplicate by ID/name\n// after\nif !batch.contains_table(\"cpu\") {\n    batch.create_table(\"cpu\")?;\n}","handlingStrategy":"validation","validationCode":"// dedupe table creations before applying\nlet mut seen = std::collections::HashSet::new();\nfor name in &table_names {\n    if !seen.insert(name.clone()) {\n        return Err(anyhow!(\"duplicate table creation for {name} in one batch\"));\n    }\n}","typeGuard":"fn is_new_table(batch: &CatalogBatch, id: TableId, name: &str) -> bool {\n    !batch.tables.keys().any(|k| k.id == id)\n        && batch.tables.values().all(|t| t.table.name != name)\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["rust","panic","catalog","duplicate"],"backgroundTag":"internal-invariant-violation","analyzedSha":"06200ef96ba82c5f6727e5038a83af8e722c6875","analyzedAt":"2026-09-19T12:55:30.003Z","contentChangedAt":"2026-09-19T12:55:30.003Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}