linera-io/linera-protocol · critical · ExecutionError

UnexpectedOracleResponse

UnexpectedOracleResponse

Error message

ExecutionError::UnexpectedOracleResponse

What it means

During replay, TransactionTracker holds the list of oracle responses recorded when the block was first executed. into_outcome verifies that this list is fully consumed; UnexpectedOracleResponse means the recorded list still had responses left over — the re-execution performed fewer oracle queries than were originally recorded.

Source

Thrown at linera-execution/src/transaction_tracker.rs:392

            local_time: _,
            transaction_index: _,
            next_application_index,
            next_chain_index,
            events,
            blobs,
            previously_created_blobs: _,
            operation_result,
            streams_to_process,
            blobs_published,
            free_blob_ids,
            prepared_checkpoint: _,
        } = self;
        ensure!(
            streams_to_process.is_empty(),
            ExecutionError::UnprocessedStreams
        );
        if let Some(mut responses) = replaying_oracle_responses {
            ensure!(
                responses.next().is_none(),
                ExecutionError::UnexpectedOracleResponse
            );
        }
        let blobs = blobs
            .into_iter()
            .map(|(blob_id, content)| Blob::new_with_hash_unchecked(blob_id, content))
            .collect::<Vec<_>>();
        Ok(TransactionOutcome {
            outgoing_messages,
            oracle_responses,
            next_application_index,
            next_chain_index,
            events,
            blobs,
            operation_result: operation_result.unwrap_or_default(),
            blobs_published,
            free_blob_ids,

View on GitHub (pinned to 6c226ddcb3)

Solutions

  1. Recompile/redeploy so the replayed block executes the exact bytecode it was recorded with (the published blob must match)
  2. Discard the stale checkpoint and re-download blocks and recorded responses from a committee validator
  3. Audit the application for conditional oracle reads (a branch that sometimes skips a query) and make read patterns stable per code path
Defensive patterns

Strategy: try-catch

Try / catch

Match ExecutionError::UnexpectedOracleResponse alongside OracleResponseMismatch around replay and checkpoint-apply calls. Both indicate replay divergence: halt the replay, discard the checkpoint, resynchronize from a validator, and re-validate rather than continuing.

Prevention

When it happens

Trigger: Replaying a block whose execution path skipped an oracle query the original run performed — usually because application code or state changed between the recorded run and the replay, or a checkpoint was applied (apply_checkpoint) with a stale response list.

Common situations: Changing WASM application bytecode while historical blocks still need replay; replaying from a checkpoint whose recorded oracle responses no longer line up with the replayed transactions; non-deterministic control flow that conditionally skips oracle reads.

Related errors


AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22). Data as JSON: /api/errors/a1e60b64b4dc8172. Report an issue: GitHub.