influxdata/influxdb · error

tried to unwrap a retry as success

Error message

tried to unwrap a retry as success

What it means

The catalog uses a Prompt<S, R> type that encodes 'apply result' as either Success(S) or Retry(R). unwrap_success() panics if called on a Retry variant. This guards against code assuming an operation will never ask for a retry; calling it on a Retry means the caller mis-modeled the outcome (a retry was requested where only success was legal).

Solutions

  1. Match on the Prompt and handle the Retry variant explicitly instead of unwrapping
  2. Use the appropriate accessor (unwrap_retry / as_retry) after checking the variant
  3. Ensure batches are applied in sequence order so a Retry is never produced on the success-only path
  4. If the retry condition is legitimately impossible in your flow, assert with a contextual message and log the retry payload

Example fix

// before
let schema = prompt.unwrap_success();
// after
let schema = match prompt {
    Prompt::Success(s) => s,
    Prompt::Retry(r) => return Err(anyhow!("apply deferred: retry required: {r:?}")),
};
Defensive patterns

Strategy: type-guard

Validate before calling

// check the variant before unwrapping
if matches!(prompt, Prompt::Retry(_)) {
    return Err(anyhow!("apply returned retry; success assumed"));
}

Type guard

fn is_success<S, R>(p: &Prompt<S, R>) -> bool {
    matches!(p, Prompt::Success(_))
}

Try / catch

match prompt {
    Prompt::Success(s) => Ok(s),
    Prompt::Retry(r) => Err(anyhow!("unexpected retry: {r:?}")),
}

Prevention

When it happens

Trigger: Calling unwrap_success() on a Prompt that holds Retry — typically when an apply/replay step returned Retry (e.g. because a prerequisite state wasn't reached) and the caller unconditionally unwraps.

Common situations: Catalog batch application/replay during startup where an earlier batch must be applied first and the code assumed ordered input; custom code extending the catalog applying batches without checking the Prompt variant.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19). Data as JSON: /api/errors/d92358aa991b0c8d. Report an issue: GitHub.

Appendix: source

Thrown at influxdb3_catalog/src/catalog/versions/v2/update.rs:2069

        CatalogBatch::database(
            txn.time_ns,
            txn.database_schema.id,
            Arc::clone(&txn.database_schema.name),
            ops,
        )
    }
}

#[derive(Debug)]
pub enum Prompt<Success = (), Retry = ()> {
    Success(Success),
    Retry(Retry),
}

impl<S, R> Prompt<S, R> {
    pub fn unwrap_success(self) -> S {
        let Self::Success(s) = self else {
            panic!("tried to unwrap a retry as success");
        };
        s
    }
}

#[derive(Debug, Clone, Eq, PartialEq)]
pub(crate) struct Repo<K: Hash + Eq + Copy + Ord, V: CatalogResource> {
    /// Store for items in the repository
    pub(crate) repo: IndexMap<K, V>,
    /// Bi-directional map of identifiers to names in the repository
    pub(crate) id_name_map: BiHashMap<K, Arc<str>>,
}

impl<K: Hash + Eq + Copy + Ord, V: CatalogResource> Repo<K, V> {
    pub(crate) fn new() -> Self {
        Self {
            repo: IndexMap::new(),
            id_name_map: bimap::BiHashMap::with_hashers(

View on GitHub (pinned to 06200ef96b)