influxdata/influxdb · error

just got this index

Error message

just got this index

What it means

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.

Source

Thrown at core/object_store_mem_cache/src/cache_system/s3_fifo_cache/ordered_set.rs:120

    ///
    /// Returns `true` if the entry was part of the set.
    ///
    /// # Runtime Complexity
    /// This amortizes to `O(1)`.
    ///
    /// If the number of tombstones after the removal would be larger than 50% of the entries within the [`IndexSet`],
    /// this will compact the data by removing all the tombstones. That will effectively rewrite the [`IndexSet`] and
    /// has `O(n)` complexity.
    pub(crate) fn remove(&mut self, o: &T) -> bool {
        match self.set.get_index_of(&Entry::Data(o)) {
            Some(idx) => {
                // replace entry w/ tombstone
                self.set.insert(Entry::Tombstone(self.tombstone_counter));
                self.tombstone_counter += 1;
                self.n_tombstones += 1;
                self.set
                    .swap_remove_index(idx)
                    .expect("just got this index");

                // account memory size
                self.memory_size -= o.size();

                // maybe compact data
                // NOTE: Use `>`, NOT `>=` here to prevent compactions for empty containers
                if self.n_tombstones * 2 > self.set.len() {
                    self.set.retain(|entry| matches!(entry, Entry::Data(_)));
                    self.n_tombstones = 0;
                }

                true
            }
            None => false,
        }
    }

    /// Number of entries in set.

View on GitHub (pinned to d28e26e048)

Solutions

  1. Reproduce with RUST_BACKTRACE=1 and reduce it; this is an upstream bug in object_store_mem_cache, not a usage error.
  2. 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.
  3. Check whether the state came from new_from_snapshot and validate the snapshot bytes.
  4. Report the issue upstream with the failing key/entry sequence.
Defensive patterns

Strategy: try-catch

Try / catch

let removed = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
    ordered_set.remove(&key)
}));
if removed.is_err() {
    // internal invariant broken: capture state, file upstream issue,
    // then rebuild the affected queue rather than continuing with suspect state
    recreate_cache_state();
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of influxdata/influxdb@d28e26e048 (2026-08-16). Data as JSON: /api/errors/7e8d760ca8459cae. Report an issue: GitHub.