{"record":{"id":"c90f25b4b620e052","repo":"Pumpkin-MC/Pumpkin","slug":"unexpected-event-type-c90f25","errorCode":null,"errorMessage":"unexpected event type","messagePattern":"unexpected event type","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/events/vehicle.rs","lineNumber":43,"sourceCode":"use pumpkin_util::math::vector3::Vector3;\n\nimpl ToFromWasmEvent for VehicleBlockCollisionEvent {\n    fn to_wasm_event(&self, _state: &mut PluginHostState) -> Event {\n        Event::VehicleBlockCollisionEvent(VehicleBlockCollisionEventData {\n            vehicle_id: self.vehicle_id,\n            block_pos: to_wasm_block_position(self.block_pos),\n            cancelled: self.cancelled,\n        })\n    }\n\n    fn from_wasm_event(event: Event, _state: &mut PluginHostState) -> Self {\n        match event {\n            Event::VehicleBlockCollisionEvent(data) => Self {\n                vehicle_id: data.vehicle_id,\n                block_pos: from_wasm_block_position(data.block_pos),\n                cancelled: data.cancelled,\n            },\n            _ => panic!(\"unexpected event type\"),\n        }\n    }\n\n    fn apply_wasm_event(&mut self, event: Event, state: &mut PluginHostState) {\n        cleanup_event(&event, state);\n        if let Event::VehicleBlockCollisionEvent(data) = event {\n            self.block_pos = from_wasm_block_position(data.block_pos);\n            self.cancelled = data.cancelled;\n        }\n    }\n}\n\nimpl ToFromWasmEvent for VehicleCollisionEvent {\n    fn to_wasm_event(&self, _state: &mut PluginHostState) -> Event {\n        Event::VehicleCollisionEvent(VehicleCollisionEventData {\n            vehicle_id: self.vehicle_id,\n            cancelled: self.cancelled,\n        })","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/Pumpkin-MC/Pumpkin/blob/8d4639e25a57c15e47448ec327c780d41bbf2356/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/events/vehicle.rs#L25-L61","documentation":"The WASM plugin host's per-event-type conversion layer (`from_wasm_event`) received an `Event` variant other than `VehicleBlockCollisionEvent` and panics. Each vehicle event adapter is only ever supposed to be dispatched with its own variant; hitting the catch-all `_` arm means the event dispatch/matching table is out of sync with the event enum. This is an internal invariant of the plugin bridge, not a plugin author error.","triggerScenarios":"Dispatching a plugin event to the VehicleBlockCollisionEvent handler with an `Event` enum variant other than `Event::VehicleBlockCollisionEvent` — i.e. a bug in the event router (crate event enum and WIT v0_1 dispatch table mismatched after adding/renaming a variant).","commonSituations":"Developers adding a new `Event` variant to the core enum but forgetting to register it in the WIT v0_1 event dispatch table; refactoring event names so the router falls through to the wrong handler; running a plugin built against a different API version whose event IDs are remapped.","solutions":["Audit the event dispatch/matching code that calls `from_wasm_event` for the vehicle-block-collision adapter and ensure it only routes `Event::VehicleBlockCollisionEvent`","Verify the core `Event` enum and the WIT v0_1 event enum are in sync (regenerate WIT bindings if they drifted)","Replace the panic with a logged warning + event drop if a plugin API version may legitimately send unknown variants","Write a unit test that constructs every `Event` variant and asserts it dispatches to its matching adapter"],"exampleFix":"// before\n_ => panic!(\"unexpected event type\"),\n// after\nother => log::warn!(\"event {:?} misrouted to VehicleBlockCollisionEvent handler; dropping\", std::mem::discriminant(&other))","handlingStrategy":"type-guard","validationCode":"// host-side guard before conversion\nif !matches!(event, Event::VehicleBlockCollisionEvent(_)) {\n    log::warn!(\"event misrouted to VehicleBlockCollisionEvent adapter\");\n    return;\n}","typeGuard":"fn is_vehicle_block_collision(e: &Event) -> bool {\n    matches!(e, Event::VehicleBlockCollisionEvent(_))\n}","tryCatchPattern":"// panic is not catchable via Result; use catch_unwind at the dispatch boundary\nlet result = std::panic::catch_unwind(AssertUnwindSafe(|| adapter.from_wasm_event(event, state)));\nif result.is_err() { log::error!(\"event conversion panicked; event dropped\"); }","preventionTips":["Keep the WIT event enum and core Event enum generated from one source","Add an exhaustive dispatch table test over all Event variants","Prefer returning Result over panic in event adapters","Run plugin event tests after every enum change"],"tags":["panic","wasm-plugin","event-dispatch","internal-invariant"],"backgroundTag":"internal-invariant-violation","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"}