{"record":{"id":"cbad2619e92ebd89","repo":"Pumpkin-MC/Pumpkin","slug":"unexpected-event-cbad26","errorCode":null,"errorMessage":"unexpected event","messagePattern":"unexpected event","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/pumpkin-plugin-api/src/events/world/async_structure_spawn.rs","lineNumber":13,"sourceCode":"use super::super::FromIntoEvent;\nuse crate::wit::pumpkin::plugin::event::{AsyncStructureSpawnEventData, Event, EventType};\n\n/// Event triggered when a structure is asynchronously spawned.\npub struct AsyncStructureSpawnEvent;\nimpl FromIntoEvent for AsyncStructureSpawnEvent {\n    const EVENT_TYPE: EventType = EventType::AsyncStructureSpawnEvent;\n    type Data = AsyncStructureSpawnEventData;\n\n    fn data_from_event(event: Event) -> Self::Data {\n        match event {\n            Event::AsyncStructureSpawnEvent(data) => data,\n            _ => panic!(\"unexpected event\"),\n        }\n    }\n\n    fn data_into_event(data: Self::Data) -> Event {\n        Event::AsyncStructureSpawnEvent(data)\n    }\n}\n","sourceCodeStart":1,"sourceCodeEnd":21,"githubUrl":"https://github.com/Pumpkin-MC/Pumpkin/blob/8d4639e25a57c15e47448ec327c780d41bbf2356/crates/pumpkin-plugin-api/src/events/world/async_structure_spawn.rs#L1-L21","documentation":"This panic fires inside `FromIntoEvent::data_from_event` for `AsyncStructureSpawnEvent` when the passed `Event` variant is anything other than `Event::AsyncStructureSpawnEvent`. The conversion unwraps typed payload after type-based routing; receiving any other variant violates the invariant that the event bus delivers only matching events and results in a panic inside the plugin handler.","triggerScenarios":"Dispatching a foreign event variant to an `AsyncStructureSpawnEvent` handler, or a custom plugin harness invoking the generated conversion with a mismatched `Event`.","commonSituations":"Hand-written dispatch tables in alternate hosts; host/plugin ABI skew where `Event` variants changed; test fixtures passing one shared event to multiple handlers.","solutions":["Correct routing so only `Event::AsyncStructureSpawnEvent` reaches this handler.","Align plugin API versions between host and plugin to eliminate enum drift.","Construct `Event::AsyncStructureSpawnEvent(data)` explicitly in custom harnesses.","Add a debug assertion comparing `event.event_type()` with `EventType::AsyncStructureSpawnEvent` before conversion."],"exampleFix":"// before\nhandler(Event::ChunkLoadEvent(data)) // wrong variant\n// after\nhandler(Event::AsyncStructureSpawnEvent(data))","handlingStrategy":"type-guard","validationCode":"assert!(matches!(event, Event::AsyncStructureSpawnEvent(_)), \"handler requires Event::AsyncStructureSpawnEvent\");","typeGuard":"fn as_async_structure_spawn(ev: &Event) -> Option<&AsyncStructureSpawnEventData> {\n    if let Event::AsyncStructureSpawnEvent(d) = ev { Some(d) } else { None }\n}","tryCatchPattern":"// guard before dispatch:\nif let Event::AsyncStructureSpawnEvent(data) = event { handle(data) } else { log::warn!(\"non-spawn event in structure-spawn handler\") }","preventionTips":["Key custom event buses on `EventType` and carry only the matching variant.","Sync host/plugin versions to avoid `Event` enum drift.","Avoid sharing one event fixture across multiple handlers in tests.","Validate registration tables with a startup self-check."],"tags":["rust","panic","events","plugin-api","world"],"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"}