Pumpkin-MC/Pumpkin · error
unexpected event
Error message
unexpected event
What it means
This panic fires in `FromIntoEvent::data_from_event` when an `Event` passed to `EntityRemoveEvent`'s converter carries any variant other than `Event::EntityRemoveEvent`. The trait bridges the WIT-generated `Event` enum to a specific event's typed `Data`, and the match arm expects the host/plugin dispatch layer to always pair the event type with its matching variant. Receiving a mismatched variant means the event dispatch plumbing violated that pairing invariant, so the library aborts rather than silently coerce wrong data.
Solutions
- Verify the host and the pumpkin-plugin-api crate use matching versions so `EventType::EntityRemoveEvent` maps to `Event::EntityRemoveEvent`
- Check the event dispatch/registration code routes only `EventType::EntityRemoveEvent` to `EntityRemoveEvent`'s converter
- If writing a dispatcher, filter events by `EVENT_TYPE` before calling `data_from_event`
- Replace the panic with a logged error or `Result` return to fail gracefully instead of aborting the plugin host
Example fix
// before
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::EntityRemoveEvent(data) => data,
_ => panic!("unexpected event"),
}
}
// after
fn data_from_event(event: Event) -> Result<Self::Data, Event> {
match event {
Event::EntityRemoveEvent(data) => Ok(data),
other => Err(other),
}
} Defensive patterns
Strategy: try-catch
Validate before calling
if event.event_type() != EventType::EntityRemoveEvent {
return; // skip: not an EntityRemoveEvent, do not feed to data_from_event
} Type guard
fn as_entity_remove(event: &Event) -> Option<&EntityRemoveEventData> {
match event {
Event::EntityRemoveEvent(data) => Some(data),
_ => None,
}
} Try / catch
let data = std::panic::catch_unwind(|| EntityRemoveEvent::data_from_event(event))
.unwrap_or_else(|_| { log::error!("event type mismatch for EntityRemoveEvent"); return; }); Prevention
- Always match host and pumpkin-plugin-api versions
- Dispatch events by checking `EVENT_TYPE` before calling `data_from_event`
- Never forward raw `Event` values across event-type handler boundaries
- Keep `EventType` registration keys and `Event` variants in sync
When it happens
Trigger: The only call path is `data_from_event` invoked (indirectly via `FromIntoEvent` helpers) with an `Event` whose variant is not `Event::EntityRemoveEvent` — i.e. the dispatch layer routed an event of a different type to the `EntityRemoveEvent` handler, typically when `EVENT_TYPE` tagging and the `Event` enum variant disagree (version skew between host and plugin API, or a hand-written dispatch that ignores `EventType`).
Common situations: Plugin compiled against one pumpkin-plugin-api version while the host emits an older/newer `Event` enum ordering; a custom event bus that forwards raw `Event` values without checking `EventType`; a refactored dispatcher that registers `EntityRemoveEvent` under the wrong `EventType` key.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
AI-assisted analysis of Pumpkin-MC/Pumpkin@8d4639e25a (2026-09-09).
Data as JSON: /api/errors/68505a1233811b1f.
Report an issue: GitHub.
Appendix: source
Thrown at crates/pumpkin-plugin-api/src/events/entity/entity_remove.rs:14
use crate::wit::pumpkin::plugin::event::{EntityRemoveEventData, Event, EventType};
use super::super::FromIntoEvent;
/// An event that occurs when an entity is removed from the world.
pub struct EntityRemoveEvent;
impl FromIntoEvent for EntityRemoveEvent {
const EVENT_TYPE: EventType = EventType::EntityRemoveEvent;
type Data = EntityRemoveEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::EntityRemoveEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::EntityRemoveEvent(data)
}
}
View on GitHub (pinned to 8d4639e25a)