{"record":{"id":"62824d20698319de","repo":"influxdata/influxdb","slug":"cannot-merge-table-indices-with-mismatched-identifiers","errorCode":null,"errorMessage":"Cannot merge table indices with mismatched identifiers: {expected} != {actual}","messagePattern":"Cannot merge table indices with mismatched identifiers: (.+?) != (.+?)","errorType":"error_code","errorClass":"TableIndexError","httpStatus":null,"severity":"error","filePath":"influxdb3_write/src/table_index.rs","lineNumber":49,"sourceCode":"    #[error(\"Failed to list table index snapshots from object store\")]\n    ListSnapshots(#[source] object_store::Error),\n\n    #[error(\"Failed to list table indices from object store\")]\n    ListIndices(#[source] object_store::Error),\n\n    #[error(\"Failed to load table index snapshot from object store\")]\n    LoadSnapshot(#[source] object_store::Error),\n\n    #[error(\"Failed to deserialize table index snapshot\")]\n    DeserializeSnapshot(#[source] serde_json::Error),\n\n    #[error(\"Failed to persist table index to object store\")]\n    PersistIndex(#[source] object_store::Error),\n\n    #[error(\"Failed to delete table index snapshot from object store\")]\n    DeleteSnapshot(#[source] object_store::Error),\n\n    #[error(\"Cannot merge table indices with mismatched identifiers: {expected} != {actual}\")]\n    MergeMismatch {\n        expected: TableIndexId,\n        actual: TableIndexId,\n    },\n\n    #[error(\"Failed to parse table index path from object store path\")]\n    TableIndexPath(#[source] crate::paths::PathError),\n\n    #[error(\"Failed to parse table index snapshot path from object store path\")]\n    TableIndexSnapshotPath(#[source] crate::paths::PathError),\n\n    #[error(\"Failed to update table index: join task failed\")]\n    UpdateTaskFailed(#[source] tokio::task::JoinError),\n\n    #[error(\"Object meta is missing filename\")]\n    MissingFilename,\n\n    #[error(\"Failed to parse snapshot sequence number from filename\")]","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/influxdata/influxdb/blob/06200ef96ba82c5f6727e5038a83af8e722c6875/influxdb3_write/src/table_index.rs#L31-L67","documentation":"TableIndexError::MergeMismatch is raised when merging two table indices whose TableIndexId (database/table identifiers plus node identity) do not match. Index merge logic assumes both inputs describe the same table index; a mismatch would silently corrupt the merged index, so it is rejected eagerly. This is an invariant violation rather than an I/O failure.","triggerScenarios":"Calling the merge operation (e.g. merging a loaded persisted index with a locally built one during update) where expected != actual TableIndexId — typically when a snapshot/index file belongs to a different database or table than the in-memory index being updated.","commonSituations":"Reusing or mis-pointing index cache paths across databases/tables; restoring an index snapshot into the wrong database; concurrency bugs where two tables' updates interleave; node identifier changes after failover with stale files.","solutions":["Log the expected and actual TableIndexId from the error fields to identify which object is mismatched.","Verify the index is loaded/parsed from the correct object store path for that (db_id, table_id).","Clear the corrupted/stale index object from the store and rebuild it from snapshots.","Audit code that constructs or deserializes TableIndexId to ensure it comes from the same source as the index being merged."],"exampleFix":"// before\nlet merged = local_index.merge(loaded_index); // may panic/err at runtime\n// after\nassert_eq!(local_index.id(), loaded_index.id(), \"refusing to merge indices for different tables\");\nlet merged = local_index.merge(loaded_index);","handlingStrategy":"validation","validationCode":"fn can_merge(expected: &TableIndexId, actual: &TableIndexId) -> bool { expected == actual }\n// call before merging; if false, skip or rebuild the index instead of merging","typeGuard":null,"tryCatchPattern":"match result {\n    Err(TableIndexError::MergeMismatch { expected, actual }) => {\n        error!(?expected, ?actual, \"index id mismatch; rebuilding index from snapshots\");\n        rebuild_index_from_snapshots().await\n    }\n    other => other,\n}","preventionTips":["Always load the index from the object store path derived from the same (db_id, table_id).","Never cache indices across databases/tables in shared maps without keying by TableIndexId.","After failover/restore, verify node identifiers match before merging persisted indices.","Add assertions comparing TableIndexId at merge call sites during development."],"tags":["invariant","merge","identity","influxdb3"],"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"}