Pumpkin-MC/Pumpkin · error

Cannot construct BlockShearEntityEvent from WASM

Error message

Cannot construct BlockShearEntityEvent from WASM

What it means

A deliberate panic in from_wasm_event for BlockShearEntityEvent: if the incoming WASM Event is BlockShearEntityEvent itself, the code panics because this event cannot be reconstructed from the WASM side; it is only delivered host->plugin.

Solutions

  1. Never re-emit BlockShearEntityEvent from plugin code; mutate the provided cancelled flag instead.
  2. Guard dispatch against recursive delivery of the same event to the originating plugin.
  3. Ensure generated dispatch uses to_wasm_event for host->plugin and from_wasm_event only for plugin->host events.
  4. Replace the panic with a logged error and drop the event in production builds.

Example fix

// before
Event::BlockShearEntityEvent(_) => {
    panic!("Cannot construct BlockShearEntityEvent from WASM")
}
// after
Event::BlockShearEntityEvent(_) => {
    return Err(ConversionError::UnsupportedDirection("BlockShearEntityEvent"));
}
Defensive patterns

Strategy: type-guard

Validate before calling

// BlockShearEntityEvent is host->plugin only
if matches!(event, Event::BlockShearEntityEvent(_)) && direction == Direction::WasmToHost {
    log::warn!("BlockShearEntityEvent cannot be constructed from WASM");
    return;
}

Type guard

fn is_one_way_event(event: &Event) -> bool {
    matches!(event, Event::BlockShearEntityEvent(_) | Event::BlockReceiveGameEvent(_) | Event::BlockMultiPlaceEvent(_))
}

Try / catch

let result = std::panic::catch_unwind(AssertUnwindSafe(|| convert(event, state)));
if result.is_err() {
    log::warn!("unsupported event direction; event dropped");
}

Prevention

When it happens

Trigger: Routing a BlockShearEntityEvent payload back through from_wasm_event, e.g. a plugin re-dispatching the event it received or the dispatcher calling the wrong conversion direction.

Common situations: Recursive event emission from inside a plugin callback; macro-generated code updated incorrectly; developer confusion about one-way (to-plugin-only) events.

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/dbe9ed755878ada9. Report an issue: GitHub.

Appendix: source

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

            block_pos: to_wasm_block_position(self.block_pos),
            target_world,
            target_entity_id: self.target.get_entity().entity_id,
            item,
            cancelled: self.cancelled,
        })
    }

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

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

impl ToFromWasmEvent for BlockSpreadEvent {
    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::BlockSpreadEvent(BlockSpreadEventData {
            source_pos: to_wasm_block_position(self.source_pos),
            target_pos: to_wasm_block_position(self.target_pos),
            target_world,
            new_state_id: self.new_state_id.as_u16(),
            cancelled: self.cancelled,
        })

View on GitHub (pinned to 8d4639e25a)