{"record":{"id":"59420145f1da85e9","repo":"Pumpkin-MC/Pumpkin","slug":"cannot-construct-campfirestartevent-from-wasm","errorCode":null,"errorMessage":"Cannot construct CampfireStartEvent from WASM","messagePattern":"Cannot construct CampfireStartEvent from WASM","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/events/block.rs","lineNumber":1115,"sourceCode":"            target_world,\n            item,\n            slot: self.slot,\n            cooking_time: self.cooking_time,\n            cancelled: self.cancelled,\n        })\n    }\n\n    fn apply_wasm_event(&mut self, event: Event, state: &mut PluginHostState) {\n        cleanup_event(&event, state);\n        if let Event::CampfireStartEvent(data) = event {\n            self.cooking_time = data.cooking_time;\n            self.cancelled = data.cancelled;\n        }\n    }\n\n    fn from_wasm_event(event: Event, _state: &mut PluginHostState) -> Self {\n        match event {\n            Event::CampfireStartEvent(_) => panic!(\"Cannot construct CampfireStartEvent from WASM\"),\n            _ => panic!(\"unexpected event type\"),\n        }\n    }\n}\n\nimpl ToFromWasmEvent for CauldronLevelChangeEvent {\n    fn to_wasm_event(&self, state: &mut PluginHostState) -> Event {\n        let target_world = state\n            .add_world(self.world.clone())\n            .expect(\"failed to add world resource\");\n        Event::CauldronLevelChangeEvent(CauldronLevelChangeEventData {\n            block_pos: to_wasm_block_position(self.block_pos),\n            target_world,\n            old_level: self.old_level,\n            new_level: self.new_level,\n            reason: format!(\"{:?}\", self.reason),\n            entity_id: self.entity.as_ref().map(|e| e.get_entity().entity_id),\n            cancelled: self.cancelled,","sourceCodeStart":1097,"sourceCodeEnd":1133,"githubUrl":"https://github.com/Pumpkin-MC/Pumpkin/blob/8d4639e25a57c15e47448ec327c780d41bbf2356/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/events/block.rs#L1097-L1133","documentation":"This is an intentional `panic!` in `CampfireStartEvent::from_wasm_event`. Converting a campfire-start event FROM the WASM side back into a native event is not a supported direction — the host produces this event natively and plugins only receive it, never send it. If this arm is reached, the dispatch is trying to do something the API forbids, so the library aborts loudly.","triggerScenarios":"A WASM plugin (or a macro-generated `plugin_method` bridge) attempts to raise/return `Event::CampfireStartEvent` back to the host, invoking `CampfireStartEvent::from_wasm_event`.","commonSituations":"Plugin author calls a send/raise API with a host-originated event type; macro bug mapping event direction incorrectly; plugin built against a different API version where directionality differed.","solutions":["Do not emit `CampfireStartEvent` from plugin code — it is host-to-plugin only; emit only plugin-originated events the WIT allows","Rebuild the plugin against the matching pumpkin-api version to get correct event direction metadata","Check custom macro usage that generates event dispatch and ensure read-only events are excluded from send paths","File a bug against pumpkin-api-macros if generated code routes this event backwards"],"exampleFix":"// before (plugin code)\nlet ev = Event::CampfireStartEvent(data);\nhost.send_event(ev); // panics host-side\n// after\n// only respond to CampfireStartEvent in the handler; never construct/send it\nfn on_campfire_start(&self, ev: CampfireStartEvent) { /* react only */ }","handlingStrategy":"type-guard","validationCode":"// plugin side: never send host-originated events\nconst SENDING_ALLOWED: bool = false; // CampfireStartEvent is host->plugin only\nif SENDING_ALLOWED { host.send_event(event); }","typeGuard":"fn is_plugin_originated(event: &Event) -> bool {\n    !matches!(event, Event::CampfireStartEvent(_))\n}","tryCatchPattern":"// host bridge: refuse reverse conversion gracefully instead of panicking\nif matches!(event, Event::CampfireStartEvent(_)) {\n    log::error!(\"plugin attempted to send host-only CampfireStartEvent; rejected\");\n    return;\n}","preventionTips":["Only implement handlers for host-originated events; never construct them in plugin code","Document event directionality in plugin API docs","Ensure macros exclude read-only events from send paths","Rebuild plugins against the correct API version"],"tags":["rust","wasm","panic","unsupported-direction"],"backgroundTag":"unsupported-operation","analyzedSha":"8d4639e25a57c15e47448ec327c780d41bbf2356","analyzedAt":"2026-09-09T15:32:22.916Z","contentChangedAt":"2026-09-09T15:32:22.916Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}