{"record":{"id":"47fa46044808d060","repo":"influxdata/influxdb","slug":"no-duplicate-tag","errorCode":null,"errorMessage":"no duplicate tag","messagePattern":"no duplicate tag","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"influxdb3_catalog/src/catalog/versions/v2/update.rs","lineNumber":1649,"sourceCode":"                NUM_TAG_COLUMNS_LIMIT,\n            ));\n        }\n\n        self.check_columns_limit()?;\n        self.table.check_name(tag.as_ref())?;\n\n        let id = self.table.tag_columns.next_id();\n        // Only increment if id is less than MAX.\n        if id < TagId::MAX {\n            self.table.tag_columns.set_next_id(id.next())\n        }\n        let col_id = self.next_legacy_column_id()?;\n        let tag_col = Arc::new(TagColumn::new(id, col_id, tag.as_ref()));\n\n        self.table\n            .tag_columns\n            .insert(id, Arc::clone(&tag_col))\n            .expect(\"no duplicate tag\");\n\n        let col_def = ColumnDefinition::Tag(Arc::clone(&tag_col));\n        self.table\n            .columns\n            .insert(col_def.clone())\n            .expect(\"no duplicate column\");\n\n        self.column_definitions.push(col_def.into());\n\n        Ok(tag_col)\n    }\n\n    pub(crate) fn add_time(&mut self) -> Result<Arc<TimestampColumn>> {\n        if self.table.timestamp_column.is_some() {\n            return Err(CatalogError::DuplicateColumn {\n                name: TIME_COLUMN_NAME.into(),\n                existing: InfluxColumnType::Timestamp,\n            });","sourceCodeStart":1631,"sourceCodeEnd":1667,"githubUrl":"https://github.com/influxdata/influxdb/blob/06200ef96ba82c5f6727e5038a83af8e722c6875/influxdb3_catalog/src/catalog/versions/v2/update.rs#L1631-L1667","documentation":"This is a panic raised by an `.expect(\"no duplicate tag\")` on `self.table.tag_columns.insert(id, tag_col)` while adding a tag column to a table in the InfluxDB3 catalog (influxdb3_catalog::catalog::versions::v2::update). The insert returns an error only if the map already holds a column under the same table-wide unique id, which the update transaction logic assumes can never happen. The library throws it because a violation means the in-memory TableDefinition has diverged from its log — i.e. catalog corruption — rather than a recoverable condition.","triggerScenarios":"Calling the add-tag-column path of a TableTransaction (e.g. add_tag_column) when the generated table-unique column id (from next_legacy_column_id) or the tag name already exists in table.tag_columns. This can happen if the same catalog batch is applied twice (replay of a non-idempotent update) or if id allocation is skipped/duplicated in custom catalog code.","commonSituations":"Catalog snapshot/compaction bugs where a batch is replayed on top of an already-applied state; restoring a catalog file into a newer/older schema version; hand-edited or partially-written catalog protobuf files; concurrent writers bypassing the catalog transaction lock.","solutions":["Check whether the catalog batch was applied more than once (look for duplicated ops in the write-ahead log / sequence numbers) and remove the duplicate replay.","Verify the catalog file or snapshot is not corrupted or hand-edited; restore from a known-good backup.","Ensure the column id comes from next_legacy_column_id() and that no other code path inserts into tag_columns with a manually chosen id.","If reproducible, capture the failing catalog batch and file an issue with the influxdb3 catalog maintainers — this is an internal invariant failure, not user input validation."],"exampleFix":"// before\nself.table.tag_columns.insert(id, Arc::clone(&tag_col)).expect(\"no duplicate tag\");\n// after\nif self.table.tag_columns.contains_key(&id) {\n    return Err(Error::DuplicateTagName { table: self.table.name.clone(), tag: tag.into() });\n}\nself.table.tag_columns.insert(id, Arc::clone(&tag_col)).expect(\"no duplicate tag\");","handlingStrategy":"validation","validationCode":"// Before replaying/applying a batch, check the tag isn't already a column\nif table_def.columns().any(|c| c.name() == tag_name) {\n    return Err(\"tag column already exists in table; skip duplicate batch op\");\n}","typeGuard":"fn tag_exists(table: &TableDefinition, id: &TableId) -> bool { table.tag_columns.contains_key(id) }","tryCatchPattern":null,"preventionTips":["Never apply the same catalog batch twice; track applied sequence numbers.","Always allocate column ids via next_legacy_column_id(), never hand-assign them.","Restore catalogs only from complete, consistent snapshots."],"tags":["influxdb3","catalog","panic","duplicate-key","internal-state"],"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"}