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
- Match on the Prompt and handle the Retry variant explicitly instead of unwrapping
- Use the appropriate accessor (unwrap_retry / as_retry) after checking the variant
- Ensure batches are applied in sequence order so a Retry is never produced on the success-only path
- 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
- Always match on Prompt variants; never unwrap unconditionally
- Apply catalog batches strictly in sequence order so retries cannot occur
- Centralize Prompt handling in one helper with explicit Retry policy
- Add tests covering the Retry branch of every apply path
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
- column id in series key should be valid
- duration not to overflow
- Error converting compaction level
- error reading time column
- Existing transaction for table should not exist
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)