Pumpkin-MC/Pumpkin · error
Cannot construct CampfireStartEvent from WASM
Error message
Cannot construct CampfireStartEvent from WASM
What it means
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.
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
Example fix
// before (plugin code)
let ev = Event::CampfireStartEvent(data);
host.send_event(ev); // panics host-side
// after
// only respond to CampfireStartEvent in the handler; never construct/send it
fn on_campfire_start(&self, ev: CampfireStartEvent) { /* react only */ } Defensive patterns
Strategy: type-guard
Validate before calling
// plugin side: never send host-originated events
const SENDING_ALLOWED: bool = false; // CampfireStartEvent is host->plugin only
if SENDING_ALLOWED { host.send_event(event); } Type guard
fn is_plugin_originated(event: &Event) -> bool {
!matches!(event, Event::CampfireStartEvent(_))
} Try / catch
// host bridge: refuse reverse conversion gracefully instead of panicking
if matches!(event, Event::CampfireStartEvent(_)) {
log::error!("plugin attempted to send host-only CampfireStartEvent; rejected");
return;
} Prevention
- 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
When it happens
Trigger: 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`.
Common situations: 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.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Cannot construct CauldronLevelChangeEvent from WASM
- failed to add world resource
- failed to add player resource
- unexpected event type
- Cannot construct BlockFertilizeEvent from WASM
AI-assisted analysis of Pumpkin-MC/Pumpkin@8d4639e25a (2026-09-09).
Data as JSON: /api/errors/59420145f1da85e9.
Report an issue: GitHub.
Appendix: source
Thrown at crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/events/block.rs:1115
target_world,
item,
slot: self.slot,
cooking_time: self.cooking_time,
cancelled: self.cancelled,
})
}
fn apply_wasm_event(&mut self, event: Event, state: &mut PluginHostState) {
cleanup_event(&event, state);
if let Event::CampfireStartEvent(data) = event {
self.cooking_time = data.cooking_time;
self.cancelled = data.cancelled;
}
}
fn from_wasm_event(event: Event, _state: &mut PluginHostState) -> Self {
match event {
Event::CampfireStartEvent(_) => panic!("Cannot construct CampfireStartEvent from WASM"),
_ => panic!("unexpected event type"),
}
}
}
impl ToFromWasmEvent for CauldronLevelChangeEvent {
fn to_wasm_event(&self, state: &mut PluginHostState) -> Event {
let target_world = state
.add_world(self.world.clone())
.expect("failed to add world resource");
Event::CauldronLevelChangeEvent(CauldronLevelChangeEventData {
block_pos: to_wasm_block_position(self.block_pos),
target_world,
old_level: self.old_level,
new_level: self.new_level,
reason: format!("{:?}", self.reason),
entity_id: self.entity.as_ref().map(|e| e.get_entity().entity_id),
cancelled: self.cancelled,View on GitHub (pinned to 8d4639e25a)