Hmbown/CodeWhale · error

operation_key binding does not match its persisted Runtime…

Error message

operation_key binding does not match its persisted Runtime turn

What it means

Consistency guard in the turn-operation binding check: the persisted binding's thread, fingerprints, and (when requested) turn id all match, but the turn record loaded from the store does not correspond to that persisted Runtime turn — the durable turn and its binding disagree.

Solutions

  1. Inspect the turn store and operation binding tables for divergence (crash mid-write) and repair the affected records.
  2. Retry after Runtime recovery rebuilds consistent state.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at crates/tui/src/runtime_threads.rs:9072 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/a5244b4699dbdf9a. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/runtime_threads.rs:9072

            return Ok(None);
        };
        if persisted.thread_id != requested.thread_id
            || persisted.operation_key_fingerprint != requested.operation_key_fingerprint
            || persisted.request_fingerprint != requested.request_fingerprint
            || prepared
                .requested_turn_id
                .as_deref()
                .is_some_and(|turn_id| persisted.turn_id != turn_id)
        {
            bail!("operation_key is already bound to a different turn request");
        }
        let turn_path = self.store.turn_path(&persisted.turn_id)?;
        if !turn_path.exists() {
            bail!("operation_key binding is incomplete; retry after Runtime recovery");
        }
        let turn = self.store.load_turn(&persisted.turn_id)?;
        if turn.id != persisted.turn_id || turn.thread_id != persisted.thread_id {
            bail!("operation_key binding does not match its persisted Runtime turn");
        }
        Ok(Some(turn))
    }

    /// Read the exact durable binding without replaying, recovering, loading an
    /// engine, or creating even a claim-lock file. The shared claim prevents a
    /// reader from observing admission records that can still be rolled back.
    pub(crate) fn lookup_turn_operation(
        &self,
        thread_id: &str,
        operation_key: &str,
    ) -> Result<Option<TurnRecord>, RuntimeTurnOperationLookupError> {
        use RuntimeTurnOperationLookupError::{Incomplete, InvalidRequest, Unavailable};
        validated_record_id(thread_id, "thread id").map_err(|_| InvalidRequest)?;
        let fingerprint =
            runtime_turn_operation_key_fingerprint(&self.store.owner_id, thread_id, operation_key)
                .map_err(|_| InvalidRequest)?;
        checked_existing_runtime_store_dir(&self.store.turn_operations_dir)

View on GitHub (pinned to 73e0f67d83)