RyanCodrai/turbovec · error

{e}

Error message

{e}

What it means

TurboQuantIndex::search is the panicking wrapper around search_with_allowlist: on any search error (e.g. invalid query values or a query buffer whose length is not a multiple of dim) it re-panics with the error's Display message. The panic intentionally preserves the descriptive payload instead of hiding it behind a Debug render.

Source

Thrown at turbovec/src/id_map.rs:603

    /// - If any query coordinate is non-finite or has magnitude `>= 1e16`.
    ///
    /// This is the panicking form, matching
    /// [`TurboQuantIndex::search`](crate::TurboQuantIndex::search). Use
    /// [`Self::search_with_allowlist`] with `allowlist = None` for the
    /// same search as a `Result`. Neither condition can fire on an index
    /// with no committed `dim` — that case returns the empty result
    /// before any validation.
    pub fn search(&self, queries: &[f32], k: usize) -> (Vec<f32>, Vec<u64>) {
        // Passing `None` rules out the two allowlist variants, but not
        // the query-shape ones, which `search_with_allowlist` now
        // returns rather than letting escape as a panic from inside
        // (#412). So this cannot be an `.expect` on "cannot fail": it
        // re-panics with the error's `Display`, exactly as
        // `TurboQuantIndex::search_with_mask` does, which keeps the
        // payload the descriptive message it has always been instead of
        // burying it behind a `Debug` rendering.
        self.search_with_allowlist(queries, k, None)
            .unwrap_or_else(|e| panic!("{e}"))
    }

    /// Search restricted to the given `allowlist` of external ids.
    ///
    /// `allowlist`, when `Some`, restricts the returned top-`k` to ids in the
    /// allowlist. The allowlist is deduplicated: the effective result count
    /// per query is `min(k, number of unique ids in allowlist)`, so repeated
    /// ids don't widen the result.
    ///
    /// Returns [`SearchError::AllowlistEmpty`] if `allowlist` is `Some`
    /// and empty, or [`SearchError::UnknownId`] if it contains an id not
    /// currently present in the index. Duplicate ids in the allowlist are
    /// accepted and deduplicated.
    ///
    /// The query-shape conditions are reported the same way: a `queries`
    /// length that is not a whole multiple of the index dim yields
    /// [`SearchError::QueryBufferNotMultipleOfDim`], and a non-finite or
    /// out-of-range coordinate yields [`SearchError::InvalidQueryValue`].

View on GitHub (pinned to ccab9f325e)

Solutions

  1. Use try_search_with_allowlist (the Result-returning form) and handle the error instead of panicking.
  2. Validate queries before searching: all coords finite and |v| < 1e16, and queries.len() % dim == 0.
  3. Fix the upstream producer of the query vectors (embedding model or batching code) so buffers are complete and finite.

Example fix

// before
let results = index.search(&queries, 10); // panics on bad input
// after
match index.try_search_with_allowlist(&queries, 10, None) {
    Ok(r) => /* use r */,
    Err(e) => eprintln!("bad query batch: {e}"),
}
Defensive patterns

Strategy: try-catch

Validate before calling

assert queries.chunks(dim).all(|c| c.len() == dim);
assert!(queries.iter().all(|v| v.is_finite() && v.abs() < 1e16));

Type guard

fn valid_queries(q: &[f32], dim: usize) -> bool {
    q.len() % dim == 0 && q.iter().all(|v| v.is_finite() && v.abs() < 1e16)
}

Try / catch

// Rust: prefer the Result API instead of catching panics
match index.try_search_with_allowlist(&queries, k, None) {
    Ok(res) => res,
    Err(e) => { log::error!("search failed: {e}"); Vec::new() }
}

Prevention

When it happens

Trigger: Calling search(queries, k) where queries contains NaN/inf or |value| >= 1e16 coordinates, or where queries.len() is not a multiple of the index dimension (any SearchError variant from try_search_with_mask / try_search_with_allowlist).

Common situations: Feeding unnormalized or corrupted embedding vectors into search; batching queries by concatenating buffers and leaving a partial vector at the end; dimension mismatch between the index and query model.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of RyanCodrai/turbovec@ccab9f325e (2026-09-06). Data as JSON: /api/errors/d56e1e384b9501fb. Report an issue: GitHub.