Pumpkin-MC/Pumpkin · error

Cannot construct EntityBlockFormEvent from WASM

Error message

Cannot construct EntityBlockFormEvent from WASM

What it means

`from_wasm_event` for EntityBlockFormEvent panics if it is handed an Event::EntityBlockFormEvent. The event only flows host->plugin; returning it from a plugin to the host is deliberately unsupported, so this arm is a guard panic.

Solutions

  1. Change the plugin to not return the EntityBlockFormEvent it received.
  2. Regenerate plugin bindings with the correct SDK so the handler returns the expected type.
  3. Use the event's mutation/cancellation API instead of returning the event.
  4. Align host and plugin WIT versions.

Example fix

// plugin side, before
fn on_block_form(e: EntityBlockFormEvent) -> Event { Event::EntityBlockFormEvent(e) }
// after
fn on_block_form(e: EntityBlockFormEvent) -> Event { e.set_cancelled(false); /* no re-emit */ }
Defensive patterns

Strategy: validation

Validate before calling

// plugin side: assert handler never returns block-form events
assert!(!matches!(ret, Some(Event::EntityBlockFormEvent(_))));

Type guard

fn is_entity_block_form(e: &Event) -> bool { matches!(e, Event::EntityBlockFormEvent(_)) }

Prevention

When it happens

Trigger: A plugin returns Event::EntityBlockFormEvent from a handler, and the host's from_wasm_event conversion is invoked with it.

Common situations: Plugin code echoing back the event object; SDK bindings generating a wrong return type for the block-form event handler; hand-written bindings in another plugin language.

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


AI-assisted analysis of Pumpkin-MC/Pumpkin@8d4639e25a (2026-09-09). Data as JSON: /api/errors/a0b3f361b156beba. Report an issue: GitHub.

Appendix: source

Thrown at crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/events/block.rs:1211

            block_pos: to_wasm_block_position(self.block_pos),
            target_world,
            new_state_id: self.new_state_id.as_u16(),
            cancelled: self.cancelled,
        })
    }

    fn apply_wasm_event(&mut self, event: Event, state: &mut PluginHostState) {
        cleanup_event(&event, state);
        if let Event::EntityBlockFormEvent(data) = event {
            self.new_state_id = BlockStateId::new_or_air(data.new_state_id);
            self.cancelled = data.cancelled;
        }
    }

    fn from_wasm_event(event: Event, _state: &mut PluginHostState) -> Self {
        match event {
            Event::EntityBlockFormEvent(_) => {
                panic!("Cannot construct EntityBlockFormEvent from WASM")
            }
            _ => panic!("unexpected event type"),
        }
    }
}

impl ToFromWasmEvent for FluidLevelChangeEvent {
    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::FluidLevelChangeEvent(FluidLevelChangeEventData {
            block_pos: to_wasm_block_position(self.block_pos),
            target_world,
            new_state_id: self.new_state_id.as_u16(),
            cancelled: self.cancelled,
        })
    }

View on GitHub (pinned to 8d4639e25a)