{"record":{"id":"55e6ee320eac7ef8","repo":"linera-io/linera-protocol","slug":"oracleresponsemismatch","errorCode":"OracleResponseMismatch","errorMessage":"ExecutionError::OracleResponseMismatch","messagePattern":"ExecutionError::OracleResponseMismatch","errorType":"exception","errorClass":"ExecutionError","httpStatus":null,"severity":"critical","filePath":"linera-execution/src/transaction_tracker.rs","lineNumber":339,"sourceCode":"                                first_index,\n                                next_index,\n                            }\n                        },\n                    )\n                    .collect();\n                (app_id, updates)\n            })\n            .collect()\n    }\n\n    /// Adds the oracle response to the record.\n    /// If replaying, it also checks that it matches the next replayed one and returns `true`.\n    pub fn replay_oracle_response(\n        &mut self,\n        oracle_response: OracleResponse,\n    ) -> Result<bool, ExecutionError> {\n        let replaying = if let Some(recorded_response) = self.next_replayed_oracle_response()? {\n            ensure!(\n                recorded_response == oracle_response,\n                ExecutionError::OracleResponseMismatch\n            );\n            true\n        } else {\n            false\n        };\n        self.oracle_responses.push(oracle_response);\n        Ok(replaying)\n    }\n\n    /// If in replay mode, returns the next oracle response, or an error if it is missing.\n    ///\n    /// If not in replay mode, `None` is returned, and the caller must execute the actual oracle\n    /// to obtain the value.\n    ///\n    /// In both cases, the value (returned or obtained from the oracle) must be recorded using\n    /// `add_oracle_response`.","sourceCodeStart":321,"sourceCodeEnd":357,"githubUrl":"https://github.com/linera-io/linera-protocol/blob/6c226ddcb332ef55118dc8d0aafbd093d5420899/linera-execution/src/transaction_tracker.rs#L321-L357","documentation":"Linera records every oracle response (cross-chain balance reads, blob reads, etc.) when a block is first executed, and replays them when the block is re-executed by validators or workers. TransactionTracker::replay_oracle_response compares each freshly produced response against the next recorded one; OracleResponseMismatch means the same transaction produced a different oracle answer than the one recorded in the proposal or certificate.","triggerScenarios":"Re-executing a block via handle_request, apply_checkpoint, or blob_used where an oracle query (e.g. the balance of another chain, a blob's content) now returns a value different from the one recorded when the block was proposed and signed.","commonSituations":"Non-deterministic application logic that reads remote state which changed between proposal and validation; two executing nodes holding different views of the same cross-chain state; pruned or rewritten blobs; a malicious proposer fabricating oracle responses.","solutions":["Make application oracle reads deterministic: never branch on wall-clock time, randomness, or remote-chain state read outside the recorded oracle","Verify that all executing nodes hold the same view of the referenced chain/blob (sync storage, check pruning policy)","If you maintain a worker or custom client, treat this error as a reason to reject the block or certificate, not retry it, then re-download state from a committee validator","Check for version skew between proposer and validator: the oracle response encoding has changed across Linera versions"],"exampleFix":"// before\nlet matched = tracker.replay_oracle_response(response)?; // mismatch aborts with no context\n\n// after\nmatch tracker.replay_oracle_response(response) {\n    Ok(replaying) => { /* continue */ }\n    Err(ExecutionError::OracleResponseMismatch) => {\n        // deterministic divergence: reject the block, do not retry\n        return Err(anyhow::anyhow!(\"oracle divergence on block replay\"));\n    }\n    Err(e) => return Err(e.into()),\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"Match ExecutionError::OracleResponseMismatch explicitly around replay_oracle_response / execute_transaction calls. It is a deterministic divergence, not a transient fault: reject or quarantine the block, resynchronize state from a committee validator, and never retry the same replay against the same data.","preventionTips":["Design applications so all cross-chain and blob reads go through recorded oracle queries and return identical results on every node","Keep proposers and validators on the same Linera protocol version","Ensure blob storage and pruning policies are identical across executing nodes"],"tags":["consensus","oracle-response","replay","determinism","linera-execution"],"backgroundTag":"state-replay-divergence","analyzedSha":"6c226ddcb332ef55118dc8d0aafbd093d5420899","analyzedAt":"2026-08-22T22:49:09.787Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}