{"record":{"id":"dbe9ed755878ada9","repo":"Pumpkin-MC/Pumpkin","slug":"cannot-construct-blockshearentityevent-from-wasm","errorCode":null,"errorMessage":"Cannot construct BlockShearEntityEvent from WASM","messagePattern":"Cannot construct BlockShearEntityEvent 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":1010,"sourceCode":"            block_pos: to_wasm_block_position(self.block_pos),\n            target_world,\n            target_entity_id: self.target.get_entity().entity_id,\n            item,\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::BlockShearEntityEvent(data) = event {\n            self.cancelled = data.cancelled;\n        }\n    }\n\n    fn from_wasm_event(event: Event, _state: &mut PluginHostState) -> Self {\n        match event {\n            Event::BlockShearEntityEvent(_) => {\n                panic!(\"Cannot construct BlockShearEntityEvent from WASM\")\n            }\n            _ => panic!(\"unexpected event type\"),\n        }\n    }\n}\n\nimpl ToFromWasmEvent for BlockSpreadEvent {\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::BlockSpreadEvent(BlockSpreadEventData {\n            source_pos: to_wasm_block_position(self.source_pos),\n            target_pos: to_wasm_block_position(self.target_pos),\n            target_world,\n            new_state_id: self.new_state_id.as_u16(),\n            cancelled: self.cancelled,\n        })","sourceCodeStart":992,"sourceCodeEnd":1028,"githubUrl":"https://github.com/Pumpkin-MC/Pumpkin/blob/8d4639e25a57c15e47448ec327c780d41bbf2356/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/events/block.rs#L992-L1028","documentation":"A deliberate panic in from_wasm_event for BlockShearEntityEvent: if the incoming WASM Event is BlockShearEntityEvent itself, the code panics because this event cannot be reconstructed from the WASM side; it is only delivered host->plugin.","triggerScenarios":"Routing a BlockShearEntityEvent payload back through from_wasm_event, e.g. a plugin re-dispatching the event it received or the dispatcher calling the wrong conversion direction.","commonSituations":"Recursive event emission from inside a plugin callback; macro-generated code updated incorrectly; developer confusion about one-way (to-plugin-only) events.","solutions":["Never re-emit BlockShearEntityEvent from plugin code; mutate the provided cancelled flag instead.","Guard dispatch against recursive delivery of the same event to the originating plugin.","Ensure generated dispatch uses to_wasm_event for host->plugin and from_wasm_event only for plugin->host events.","Replace the panic with a logged error and drop the event in production builds."],"exampleFix":"// before\nEvent::BlockShearEntityEvent(_) => {\n    panic!(\"Cannot construct BlockShearEntityEvent from WASM\")\n}\n// after\nEvent::BlockShearEntityEvent(_) => {\n    return Err(ConversionError::UnsupportedDirection(\"BlockShearEntityEvent\"));\n}","handlingStrategy":"type-guard","validationCode":"// BlockShearEntityEvent is host->plugin only\nif matches!(event, Event::BlockShearEntityEvent(_)) && direction == Direction::WasmToHost {\n    log::warn!(\"BlockShearEntityEvent cannot be constructed from WASM\");\n    return;\n}","typeGuard":"fn is_one_way_event(event: &Event) -> bool {\n    matches!(event, Event::BlockShearEntityEvent(_) | Event::BlockReceiveGameEvent(_) | Event::BlockMultiPlaceEvent(_))\n}","tryCatchPattern":"let result = std::panic::catch_unwind(AssertUnwindSafe(|| convert(event, state)));\nif result.is_err() {\n    log::warn!(\"unsupported event direction; event dropped\");\n}","preventionTips":["Do not re-dispatch received events from plugin callbacks; mutate cancelled/fields instead.","Add recursion guards to event dispatch so the same plugin never receives its own re-emitted event.","Document which event types are one-way on the ToFromWasmEvent impl."],"tags":["wasm","plugin-host","panic","event-conversion"],"backgroundTag":"unsupported-operation","analyzedSha":"8d4639e25a57c15e47448ec327c780d41bbf2356","analyzedAt":"2026-09-09T15:32:22.916Z","contentChangedAt":"2026-09-09T15:32:22.916Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}