{"record":{"id":"7e8d760ca8459cae","repo":"influxdata/influxdb","slug":"just-got-this-index","errorCode":null,"errorMessage":"just got this index","messagePattern":"just got this index","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/object_store_mem_cache/src/cache_system/s3_fifo_cache/ordered_set.rs","lineNumber":120,"sourceCode":"    ///\n    /// Returns `true` if the entry was part of the set.\n    ///\n    /// # Runtime Complexity\n    /// This amortizes to `O(1)`.\n    ///\n    /// If the number of tombstones after the removal would be larger than 50% of the entries within the [`IndexSet`],\n    /// this will compact the data by removing all the tombstones. That will effectively rewrite the [`IndexSet`] and\n    /// has `O(n)` complexity.\n    pub(crate) fn remove(&mut self, o: &T) -> bool {\n        match self.set.get_index_of(&Entry::Data(o)) {\n            Some(idx) => {\n                // replace entry w/ tombstone\n                self.set.insert(Entry::Tombstone(self.tombstone_counter));\n                self.tombstone_counter += 1;\n                self.n_tombstones += 1;\n                self.set\n                    .swap_remove_index(idx)\n                    .expect(\"just got this index\");\n\n                // account memory size\n                self.memory_size -= o.size();\n\n                // maybe compact data\n                // NOTE: Use `>`, NOT `>=` here to prevent compactions for empty containers\n                if self.n_tombstones * 2 > self.set.len() {\n                    self.set.retain(|entry| matches!(entry, Entry::Data(_)));\n                    self.n_tombstones = 0;\n                }\n\n                true\n            }\n            None => false,\n        }\n    }\n\n    /// Number of entries in set.","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/influxdata/influxdb/blob/d28e26e048401c53cbb98cf2d6ab0cf1e98048ca/core/object_store_mem_cache/src/cache_system/s3_fifo_cache/ordered_set.rs#L102-L138","documentation":"OrderedSet::remove looks up the entry's index with get_index_of and then calls set.swap_remove_index(idx).expect(\"just got this index\"). The intervening insert(Entry::Tombstone(..)) only adds an element (tombstone_counter guarantees uniqueness) and never removes one, so idx stays valid; the expect is a pure internal invariant. If it fires, the OrderedSet state is corrupt or the crate has a logic bug — it is not caused by caller data.","triggerScenarios":"Removing an entry whose index bookkeeping is inconsistent with the IndexSet contents — only via a bug in OrderedSet internals, corrupted memory, or an inconsistent deserialized snapshot. A normal remove of a present/absent key returns true/false and cannot reach the panic.","commonSituations":"Local forks that changed Entry equality/hashing (making get_index_of and swap_remove_index disagree), snapshot formats that round-trip tombstones incorrectly, or hardware/allocator corruption. Otherwise unreachable.","solutions":["Reproduce with RUST_BACKTRACE=1 and reduce it; this is an upstream bug in object_store_mem_cache, not a usage error.","If you maintain a fork, verify Entry::Data/Entry::Tombstone Hash+Eq still distinguish entries as designed and that compaction (retain) keeps n_tombstones consistent.","Check whether the state came from new_from_snapshot and validate the snapshot bytes.","Report the issue upstream with the failing key/entry sequence."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"let removed = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {\n    ordered_set.remove(&key)\n}));\nif removed.is_err() {\n    // internal invariant broken: capture state, file upstream issue,\n    // then rebuild the affected queue rather than continuing with suspect state\n    recreate_cache_state();\n}","preventionTips":["If you fork/extend OrderedSet or Entry, add property-based tests (proptest) over insert/remove/compaction sequences.","Never construct inconsistent snapshots by hand; go through the crate's serialization.","Upgrade object_store_mem_cache deliberately; invariant panics usually mean version-skewed state.","Capture core/backtrace dumps for post-mortem when this fires."],"tags":["rust","internal-invariant","indexset","s3-fifo-cache","unreachable-defensive-panic"],"backgroundTag":"collection-index-invariant","analyzedSha":"d28e26e048401c53cbb98cf2d6ab0cf1e98048ca","analyzedAt":"2026-08-16T19:53:34.623Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}