linera-io/linera-protocol · error
Expected an `ExecutionError`. Got: {chain_error:#?}
Error message
Expected an `ExecutionError`. Got: {chain_error:#?} What it means
The second stage of expect_execution_error: the WorkerError was a ChainError, but the inner chain error is not the ExecutionError variant (e.g. an arithmetic/validity error, a view error, or another ChainError kind). The panic prints the full chain_error debug so the actual variant is identifiable. A third assertion (context == expected_context) follows after this stage.
Source
Thrown at linera-core/src/worker.rs:538
error => Self::ChainError(Box::new(error)),
}
}
}
#[cfg(with_testing)]
impl WorkerError {
/// Returns the inner [`ExecutionError`] in this error.
///
/// # Panics
///
/// If this is not caused by an [`ExecutionError`].
pub fn expect_execution_error(self, expected_context: ChainExecutionContext) -> ExecutionError {
let WorkerError::ChainError(chain_error) = self else {
panic!("Expected an `ExecutionError`. Got: {self:#?}");
};
let ChainError::ExecutionError(execution_error, context) = *chain_error else {
panic!("Expected an `ExecutionError`. Got: {chain_error:#?}");
};
assert_eq!(context, expected_context);
*execution_error
}
}
type ChainWorkerArc<S> = Arc<tokio::sync::RwLock<ChainWorkerState<S>>>;
type ChainWorkerWeak<S> = std::sync::Weak<tokio::sync::RwLock<ChainWorkerState<S>>>;
type ChainWorkerFuture<S> = Shared<oneshot::Receiver<ChainWorkerWeak<S>>>;
/// Each map entry is a `Shared<oneshot::Receiver<Weak<...>>>`:
///
/// - `peek()` returns `None` while a task is loading the worker from storage.
/// - `peek()` returns `Some(Ok(weak))` once the worker is loaded.
/// - `peek()` returns `Some(Err(_))` if loading failed (sender dropped).
///View on GitHub (pinned to 6c226ddcb3)
Solutions
- Read the {chain_error:#?} dump and either match that variant directly or fix the fixture so execution actually reaches the failing operation.
- Verify the expected ChainExecutionContext too — the following assert_eq!(context, expected_context) is a common next failure.
- Prefer explicit matches on the expected error shape in tests instead of blanket expect_* helpers when the error layer is uncertain.
Example fix
// before
let exec = err.expect_execution_error(ChainExecutionContext::Query); // panics on ChainError::ArithError
// after
let WorkerError::ChainError(chain_err) = err else { panic!("expected chain error") };
match *chain_err {
ChainError::ExecutionError(exec, ctx) => { assert_eq!(ctx, ChainExecutionContext::Query); /* ... */ }
other => panic!("unexpected: {other:?}"),
} Defensive patterns
Strategy: type-guard
Validate before calling
// Rust
if !matches!(&err, WorkerError::ChainError(inner) if matches!(**inner, ChainError::ExecutionError(_, _))) {
// handle the actual chain error variant instead of unwrapping
} Type guard
fn chain_error_is_execution(err: &WorkerError) -> bool {
matches!(err, WorkerError::ChainError(inner) if matches!(&**inner, ChainError::ExecutionError(..)))
} Try / catch
let WorkerError::ChainError(chain_err) = err else { panic!("expected chain error") };
match *chain_err {
ChainError::ExecutionError(exec, ctx) => { assert_eq!(ctx, expected_ctx); /* assert on exec */ }
other => panic!("unexpected chain error: {other:?}"),
} Prevention
- Read the {chain_error:#?} dump in the panic — it names the true variant.
- Also verify the ChainExecutionContext you pass matches where the error is actually raised (the next assert).
- Keep test fixtures' chain state valid so errors surface at the execution layer you intend to assert on.
When it happens
Trigger: In tests: the worker wrapped a non-execution ChainError — certificate validation failures, view/bucket errors, chain-state problems — where the test expected user-code execution to fail. The {chain_error:#?} output names the true variant.
Common situations: Tests asserting application-level execution failures that actually fail earlier at consensus/state level; changes in error taxonomy moving a case from ChainError::ExecutionError to a sibling variant; fixtures leaving the chain in a state that errors before operations run.
Related errors
- Expected an `ExecutionError`. Got: {self:#?}
- Failed to obtain a port
- {}: got non-zero error code {}
- owner should be different from spender
- invalid block export configuration: {message}
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/cfb3781966eece98.
Report an issue: GitHub.