{"record":{"id":"99a5aa478362208f","repo":"linera-io/linera-protocol","slug":"events-not-found-0","errorCode":null,"errorMessage":"Events not found: {0:?}","messagePattern":"Events not found: (.+?)","errorType":"exception","errorClass":"NodeError","httpStatus":null,"severity":"error","filePath":"linera-core/src/updater.rs","lineNumber":665,"sourceCode":"                    self.send_chain_info_up_to_heights(\n                        origin_heights,\n                        CrossChainMessageDelivery::Blocking,\n                    )\n                    .await?;\n                }\n                Err(NodeError::EventsNotFound(event_ids)) => {\n                    let mut publisher_heights = BTreeMap::new();\n                    let chain_ids = event_ids\n                        .iter()\n                        .map(|event_id| event_id.chain_id)\n                        .filter(|chain_id| !publisher_chain_ids_sent.contains(chain_id))\n                        .collect::<BTreeSet<_>>();\n                    tracing::debug!(\n                        remote_node = self.remote_node.address(),\n                        ?chain_ids,\n                        \"missing events; sending chains to validator\",\n                    );\n                    ensure!(!chain_ids.is_empty(), NodeError::EventsNotFound(event_ids));\n                    for chain_id in chain_ids {\n                        let height = self\n                            .local_node\n                            .get_next_height_to_preprocess(chain_id)\n                            .await?;\n                        publisher_heights.insert(chain_id, height);\n                        publisher_chain_ids_sent.insert(chain_id);\n                    }\n                    self.send_chain_info_up_to_heights(\n                        publisher_heights,\n                        CrossChainMessageDelivery::NonBlocking,\n                    )\n                    .await?;\n                }\n                Err(error @ NodeError::ChainError { .. }) => {\n                    // The validator rejected the proposal because of its local chain\n                    // manager state — most commonly an incompatible confirmed vote tied\n                    // to a locking block we don't yet have. The caller should pull","sourceCodeStart":647,"sourceCodeEnd":683,"githubUrl":"https://github.com/linera-io/linera-protocol/blob/6c226ddcb332ef55118dc8d0aafbd093d5420899/linera-core/src/updater.rs#L647-L683","documentation":"Raised in RemoteNodeUpdater::send_block_proposal when a validator rejects a proposal with EventsNotFound: the client maps each missing event to its publishing chain, forwards those chains' certificates to the validator, and retries — but only for publisher chains it has not already sent. If the same EventsNotFound comes back and every publisher chain is already in publisher_chain_ids_sent, there is nothing new to forward: the local node itself cannot provide those events, so the error is surfaced with the original event IDs.","triggerScenarios":"The block being proposed reads events (streams, epoch events) from publisher chains whose certificates the local node does not hold; event streams referenced by an application whose publishing chain was never synced locally; validator needing admin-chain epoch events the client lacks.","commonSituations":"Applications subscribing to streams on other chains after a wallet restore; multi-chain apps where the destination client only has message bundles but not the full publisher history; validators requiring committee/epoch events the client never downloaded.","solutions":["Before proposing, run download_certificates on every publisher chain referenced by the block (the event IDs in the error tell you which chains) so the local node holds the events","Use prepare_chain()/full chain sync so epoch and admin-chain events are available locally","Retry after syncing: once local storage has the events, forwarding them to the validator succeeds","If the events genuinely do not exist (e.g. wrong stream/index), fix the application's referenced stream indices"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Before proposing, make sure the local node holds every publisher chain your block reads.\nfor publisher in block_publisher_chains(&block) {\n    let local = client.local_node().chain_info(publisher).await?;\n    // ensure local height covers the events your application references\n    assert!(local.next_block_height > required_height[publisher]);\n}","typeGuard":"fn events_not_found(err: &chain_client::Error) -> Option<&Vec<EventId>> {\n    match err {\n        chain_client::Error::RemoteNodeError(NodeError::EventsNotFound(ids)) => Some(ids),\n        _ => None,\n    }\n}","tryCatchPattern":"match client.process_pending_block().await {\n    Err(e) if let Some(ids) = events_not_found(&e) => {\n        // ids tell you the publisher chains; download them, then retry.\n        for chain in ids.iter().map(|id| id.chain_id).collect::<BTreeSet<_>>() {\n            client.synchronize_chain_state_from_all_validators_for(chain).await?;\n        }\n        client.process_pending_block().await\n    }\n    other => other,\n}","preventionTips":["Subscribe-and-propose workflows: always sync publisher chains up to the events your block consumes first","Validate stream indices your application references exist on the publisher chain before building the block","Treat the event IDs in this error as actionable data: they name exactly which chains to fetch"],"tags":["linera","events","streams","cross-chain","sync"],"backgroundTag":"missing-cross-chain-data","analyzedSha":"6c226ddcb332ef55118dc8d0aafbd093d5420899","analyzedAt":"2026-08-22T22:49:09.787Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}