linera-io/linera-protocol · error · ExecutionError
UnprocessedStreams
UnprocessedStreams
Error message
ExecutionError::UnprocessedStreams
What it means
When a transaction finishes, TransactionTracker::into_outcome finalizes it and asserts that every stream the application created (streams_to_process) has been processed by the caller. UnprocessedStreams means the transaction created at least one stream whose events were never consumed, so converting the tracker into a TransactionOutcome is refused.
Source
Thrown at linera-execution/src/transaction_tracker.rs:387
pub fn into_outcome(self) -> Result<TransactionOutcome, ExecutionError> {
let TransactionTracker {
replaying_oracle_responses,
oracle_responses,
outgoing_messages,
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,View on GitHub (pinned to 6c226ddcb3)
Solutions
- Process every created stream before finalizing: the standard block executor does this inside execute_transaction, so if you wrap it, keep that step in your wrapper
- Upgrade node and application SDK to matching versions so stream creation and processing are both handled
- If the application should not emit streams, remove the create-stream call from its code and redeploy
Defensive patterns
Strategy: try-catch
Try / catch
Match ExecutionError::UnprocessedStreams when calling into_outcome or execute_transaction and treat it as an integration bug between the application and the executor. Do not swallow it: committing without processing the stream would lose events.
Prevention
- Use the provided block executor rather than reimplementing transaction finalization
- Keep application SDK and node versions in lockstep when your app creates streams or events
- In tests, always run the full execute_transaction path so stream processing happens
When it happens
Trigger: An application creates a new event stream via the system API during execution, but the executor never drains streams_to_process before calling into_outcome — typically a custom block executor or hand-rolled test harness that skips the stream-processing step that the standard execute_transaction path performs.
Common situations: Custom applications or SDK versions that create streams while an older node version or custom harness does not process them; protocol upgrades that introduce stream handling on one side but not the other.
Related errors
- Checkpoint precondition failed: chain has consumed system ev
- Events not found: {0:?}
- It is illegal to call function process_streams from an opera
- StreamNameTooLong
- OracleResponseMismatch
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/6968c85e037a566b.
Report an issue: GitHub.