{"record":{"id":"83b4ac1b2e7c9624","repo":"Pumpkin-MC/Pumpkin","slug":"failed-to-add-world-resource-83b4ac","errorCode":null,"errorMessage":"failed to add world resource","messagePattern":"failed to add world resource","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/events/world.rs","lineNumber":28,"sourceCode":"            },\n            pumpkin::plugin::event::{\n                ChunkLoadEventData, ChunkSaveEventData, ChunkSendEventData, Event,\n                SpawnChangeEventData, ThunderChangeEventData, WeatherChangeEventData,\n                WorldLoadEventData, WorldUnloadEventData,\n            },\n        },\n    },\n    world::{\n        chunk_load::ChunkLoad, chunk_save::ChunkSave, chunk_send::ChunkSend,\n        spawn_change::SpawnChangeEvent,\n    },\n};\n\nimpl ToFromWasmEvent for SpawnChangeEvent {\n    fn to_wasm_event(&self, state: &mut PluginHostState) -> Event {\n        let world = state\n            .add_world(self.world.clone())\n            .expect(\"failed to add world resource\");\n\n        Event::SpawnChangeEvent(SpawnChangeEventData {\n            target_world: world,\n            previous_position: to_wasm_block_position(self.previous_position),\n            previous_yaw: self.previous_yaw,\n            previous_pitch: self.previous_pitch,\n            new_position: to_wasm_block_position(self.new_position),\n            new_yaw: self.new_yaw,\n            new_pitch: self.new_pitch,\n        })\n    }\n\n    fn from_wasm_event(event: Event, state: &mut PluginHostState) -> Self {\n        match event {\n            Event::SpawnChangeEvent(data) => Self {\n                world: consume_world(state, &data.target_world),\n                previous_position: from_wasm_block_position(data.previous_position),\n                previous_yaw: data.previous_yaw,","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/Pumpkin-MC/Pumpkin/blob/8d4639e25a57c15e47448ec327c780d41bbf2356/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/events/world.rs#L10-L46","documentation":"SpawnChangeEvent::to_wasm_event calls PluginHostState::add_world, which pushes a WorldResource into the wasmtime component resource table, and unwraps the result with expect(). The only failure path is the wasmtime ResourceTable push failing (e.g. the table's resource limit is exhausted or its internal store is corrupt), so this panic means the plugin host could not register a handle for the event's world.","triggerScenarios":"A spawn-position-change event is being converted to a WIT event for a plugin while PluginHostState.resource_table cannot accept a new WorldResource entry — wasmtime's resource table is at capacity (leaked world/chunk resources never consumed) or the table is in a broken state.","commonSituations":"Long-running servers with many plugins where world resources are pushed per event but plugin instances leak them until the table's rep limit is hit; a wasmtime store/table that failed mid-lifetime; hosting an unusually large number of simultaneous plugin instances sharing one state.","solutions":["Audit plugin event handling so world/chunk resources pushed into the table are consumed and dropped via the WIT resource-drop path, preventing table exhaustion","Restart the affected plugin instance (recreate PluginHostState) to get a fresh resource table","Update wasmtime / pumpkin to a version with resource-limit fixes, or raise the component resource limits in the wasmtime store configuration","Check server logs for earlier table/store errors indicating a corrupted PluginHostState"],"exampleFix":"// before\nlet world = state\n    .add_world(self.world.clone())\n    .expect(\"failed to add world resource\");\n\n// after\nlet world = state.add_world(self.world.clone()).map_err(|e| {\n    log::error!(\"failed to add world resource: {e}\");\n    e\n})?;","handlingStrategy":"try-catch","validationCode":"// before dispatching events to plugins, confirm the host state is usable\nfn can_push_resources(state: &PluginHostState) -> bool {\n    // wasmtime ResourceTable grows dynamically; failure indicates store corruption\n    !state.is_poisoned()\n}","typeGuard":"fn is_valid_wasm_host_state(state: &PluginHostState) -> bool {\n    !state.is_poisoned()\n}","tryCatchPattern":"// host side: never expect(); convert to Result and quarantine the plugin\nmatch state.add_world(world.clone()) {\n    Ok(res) => /* continue building event */,\n    Err(e) => {\n        log::error!(\"wasm host resource push failed: {e}\");\n        disable_plugin(instance_id);\n    }\n}","preventionTips":["Always drop WIT world/chunk resources from plugin event handlers so table entries are reclaimed","Monitor resource-table growth for long-running servers","Replace expect() in host event conversion with Result propagation","Restart plugin instances periodically or on resource-limit warnings"],"tags":["wasm","plugin","panic","resource-table","internal"],"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-15T23:17:13.987Z"}