{"record":{"id":"2fe999b49082f2d6","repo":"linera-io/linera-protocol","slug":"eventsnotfound","errorCode":"EventsNotFound","errorMessage":"ExecutionError::EventsNotFound(missing_events)","messagePattern":"ExecutionError::EventsNotFound\\(missing_events\\)","errorType":"exception","errorClass":"ExecutionError","httpStatus":null,"severity":"error","filePath":"linera-execution/src/lib.rs","lineNumber":627,"sourceCode":"                        .ok_or_else(|| ExecutionError::EventsNotFound(vec![event_id]))?;\n                    let event_data: EpochEventData = bcs::from_bytes(&event)?;\n                    Ok((Epoch(epoch), event_data.blob_hash))\n                }\n            }),\n        )\n        .await;\n        let missing_events = committee_hashes\n            .iter()\n            .filter_map(|result| {\n                if let Err(ExecutionError::EventsNotFound(event_ids)) = result {\n                    return Some(event_ids);\n                }\n                None\n            })\n            .flatten()\n            .cloned()\n            .collect::<Vec<_>>();\n        ensure!(\n            missing_events.is_empty(),\n            ExecutionError::EventsNotFound(missing_events)\n        );\n        committee_hashes.into_iter().collect()\n    }\n\n    /// Returns whether a blob with the given ID is available.\n    async fn contains_blob(&self, blob_id: BlobId) -> Result<bool, ViewError>;\n\n    /// Returns whether an event with the given ID is available.\n    async fn contains_event(&self, event_id: EventId) -> Result<bool, ViewError>;\n\n    /// Adds the given blobs to the context, for use in tests.\n    #[cfg(with_testing)]\n    async fn add_blobs(\n        &self,\n        blobs: impl IntoIterator<Item = Blob> + Send,\n    ) -> Result<(), ViewError>;","sourceCodeStart":609,"sourceCodeEnd":645,"githubUrl":"https://github.com/linera-io/linera-protocol/blob/6c226ddcb332ef55118dc8d0aafbd093d5420899/linera-execution/src/lib.rs#L609-L645","documentation":"get_committee_hashes computes committee blob hashes for an epoch range: epoch 0 comes from the NetworkDescription, and every later epoch is read as an event from the admin chain's system epoch stream (EPOCH_STREAM_NAME). If any of those events cannot be loaded, all missing EventIds are collected and returned as EventsNotFound (lib.rs:627), failing chain initialization or committee resolution.","triggerScenarios":"initialize_chain or committee_for_epoch asks for epochs whose admin-chain epoch events are absent from the node's storage: not synced, pruned, or published on a different admin chain than the NetworkDescription declares.","commonSituations":"Starting a validator or client without syncing the admin chain; epoch events pruned after a checkpoint restore that did not retain the epoch stream; a misconfigured NetworkDescription with the wrong admin_chain_id; requesting an epoch above what the network has created.","solutions":["Sync the admin chain (or fetch the missing epoch-stream events from a peer) so the events exist in storage, then retry","When operating from a checkpoint, restore with a blob and event set that includes the admin chain epoch events","Verify the NetworkDescription's admin_chain_id matches the network you intend to join","Bound the requested epoch range to epochs that actually exist on the admin chain"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Pre-check that the epoch events exist before asking for committee hashes\nasync fn epoch_events_available(\n    client: &Client,\n    admin_chain: ChainId,\n    range: RangeInclusive<Epoch>,\n) -> Result<bool, ExecutionError> {\n    for epoch in range.into_iter().filter(|e| e.0 > 0) {\n        let event_id = EventId {\n            chain_id: admin_chain,\n            stream_id: StreamId::system(EPOCH_STREAM_NAME),\n            index: epoch.0,\n        };\n        if client.get_event(event_id).await?.is_none() {\n            return Ok(false);\n        }\n    }\n    Ok(true)\n}\n\nif !epoch_events_available(client, admin_chain, range.clone()).await? {\n    client.sync_admin_chain().await?; // fetch missing epoch events first\n}","typeGuard":"fn is_events_not_found(err: &ExecutionError) -> bool {\n    matches!(err, ExecutionError::EventsNotFound(_))\n}","tryCatchPattern":"let mut attempt = 0;\nloop {\n    match runtime.committee_for_epoch(range.clone()).await {\n        Ok(c) => break Ok(c),\n        Err(ref e) if is_events_not_found(e) && attempt < MAX_ATTEMPTS => {\n            // storage gap: sync the admin chain epoch events, then retry\n            client.sync_admin_chain().await?;\n            attempt += 1;\n            continue;\n        }\n        Err(e) => break Err(e),\n    }\n}","preventionTips":["Fully sync the admin chain (especially the epoch stream) before initializing chains for later epochs","When restoring from checkpoints, include the admin chain epoch events in the retained set","Verify the NetworkDescription's admin_chain_id during node setup"],"tags":["committee","epoch","admin-chain","missing-events","sync","linera"],"backgroundTag":"missing-chain-events","analyzedSha":"6c226ddcb332ef55118dc8d0aafbd093d5420899","analyzedAt":"2026-08-22T22:49:09.787Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}