{"record":{"id":"32093db2dc03daa8","repo":"linera-io/linera-protocol","slug":"failed-to-deserialize-event","errorCode":null,"errorMessage":"Failed to deserialize event","messagePattern":"Failed to deserialize event","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"linera-sdk/src/contract/runtime.rs","lineNumber":328,"sourceCode":"    /// Adds a new item to an event stream. Returns the new event's index in the stream.\n    pub fn emit(&mut self, name: StreamName, value: &Application::EventValue) -> u32 {\n        contract_wit::emit(\n            &name.into(),\n            &bcs::to_bytes(value).expect(\"Failed to serialize event\"),\n        )\n    }\n\n    /// Reads an event from a stream. Returns the event's value.\n    ///\n    /// Fails the block if the event doesn't exist.\n    pub fn read_event(\n        &mut self,\n        chain_id: ChainId,\n        name: StreamName,\n        index: u32,\n    ) -> Application::EventValue {\n        let event = contract_wit::read_event(chain_id.into(), &name.into(), index);\n        bcs::from_bytes(&event).expect(\"Failed to deserialize event\")\n    }\n\n    /// Subscribes this application to an event stream.\n    pub fn subscribe_to_events(\n        &mut self,\n        chain_id: ChainId,\n        application_id: ApplicationId,\n        name: StreamName,\n    ) {\n        contract_wit::subscribe_to_events(chain_id.into(), application_id.into(), &name.into())\n    }\n\n    /// Unsubscribes this application from an event stream.\n    pub fn unsubscribe_from_events(\n        &mut self,\n        chain_id: ChainId,\n        application_id: ApplicationId,\n        name: StreamName,","sourceCodeStart":310,"sourceCodeEnd":346,"githubUrl":"https://github.com/linera-io/linera-protocol/blob/6c226ddcb332ef55118dc8d0aafbd093d5420899/linera-sdk/src/contract/runtime.rs#L310-L346","documentation":"ContractRuntime::read_event fetches raw event bytes from a subscribed stream via the host and then does bcs::from_bytes::<Application::EventValue>. The expect panics when the bytes stored in the stream cannot be decoded into the reader application's declared EventValue type — i.e. the writer's event schema and the reader's diverged.","triggerScenarios":"Calling runtime.read_event(chain_id, name, index) for a stream produced by an application whose EventValue type differs from the Application::EventValue the reading contract was compiled with (different struct layout, enum variants, or field types).","commonSituations":"Upgrading the emitting application (new event fields) while subscribers still run the old module; two applications accidentally sharing the same StreamName with different payload types; copy-paste of a stream name across unrelated apps.","solutions":["Ensure the subscriber is built against the same crate version as the application that emits the stream, and redeploy the subscriber after the emitter's EventValue changes","Use unique StreamNames per application (namespace them with the application name) so foreign payloads never land in your stream","Design EventValue as a versioned enum (e.g. { V1(...), V2(...) }) so older readers keep decoding newer events","Replay/verify with a unit test that BCS-encodes a sample event from the emitter and decodes it as the subscriber's EventValue"],"exampleFix":"// before: raw struct that breaks on any field change\n#[derive(Serialize, Deserialize)]\nstruct EventValue { from: AccountOwner, amount: Amount }\n\n// after: versioned enum, old readers stay compatible\n#[derive(Serialize, Deserialize)]\nenum EventValue {\n    V1 { from: AccountOwner, amount: Amount },\n    V2 { from: AccountOwner, amount: Amount, memo: String },\n}","handlingStrategy":"validation","validationCode":"// Prove the emitter's schema decodes before subscribing.\n#[test]\nfn event_round_trip() {\n    let ev: EventValue = bcs::from_bytes(&emitter_sample_bytes()).unwrap();\n    assert_eq!(ev, sample_event());\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Namespace StreamNames with the application name so foreign payloads never reach your reader","Version event payloads (enum V1/V2/...) so reader/writer upgrades stay decodable","Rebuild and redeploy subscribers whenever the emitter's EventValue type changes","Add a cross-module BCS round-trip test for every stream your app reads"],"tags":["linera","rust","sdk","events","bcs","stream-subscription"],"backgroundTag":"deserialization-failed","analyzedSha":"6c226ddcb332ef55118dc8d0aafbd093d5420899","analyzedAt":"2026-08-22T22:49:09.787Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}