{"record":{"id":"d5039c6d40762a63","repo":"Pumpkin-MC/Pumpkin","slug":"failed-to-add-player-resource-d5039c","errorCode":null,"errorMessage":"failed to add player resource","messagePattern":"failed to add player resource","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/events/server.rs","lineNumber":33,"sourceCode":"        },\n    },\n    server::{\n        list_ping::ServerListPingEvent,\n        map_initialize::MapInitializeEvent,\n        packet::{PacketReceivedEvent, PacketSentEvent},\n        server_broadcast::ServerBroadcastEvent,\n        server_command::ServerCommandEvent,\n        server_load::{LoadType, ServerLoadEvent},\n        server_tick_end::ServerTickEndEvent,\n        server_tick_start::ServerTickStartEvent,\n    },\n};\n\nimpl ToFromWasmEvent for PacketReceivedEvent {\n    fn to_wasm_event(&self, state: &mut PluginHostState) -> Event {\n        let player_res = state\n            .add_player(self.player.clone())\n            .expect(\"failed to add player resource\");\n\n        let packet = match self.player.client.as_ref() {\n            ClientPlatform::Java(client) => {\n                let version = client.version.load();\n                generated_packets::deserialize_java_serverbound_packet(\n                    self.packet_id,\n                    &self.payload,\n                    version,\n                )\n                .map_or(ServerboundPacket::Unknown, ServerboundPacket::Java)\n            }\n            ClientPlatform::Bedrock(_) => {\n                generated_packets::deserialize_bedrock_serverbound_packet(\n                    self.packet_id,\n                    &self.payload,\n                )\n                .map_or(ServerboundPacket::Unknown, ServerboundPacket::Bedrock)\n            }","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/Pumpkin-MC/Pumpkin/blob/8d4639e25a57c15e47448ec327c780d41bbf2356/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/events/server.rs#L15-L51","documentation":"When converting a PacketReceivedEvent into its WIT representation, to_wasm_event calls state.add_player(...) to expose the player as a WASM resource. If add_player returns an Err (e.g. resource table limits exceeded or an internal store failure), .expect panics with 'failed to add player resource'. The plugin host cannot represent the player in the WASM resource table, so event delivery is aborted.","triggerScenarios":"A packet is received from a player and the event is forwarded to a WASM plugin while state.add_player fails — typically due to WASM resource-table exhaustion, a duplicate/invalid player handle, or a corrupted PluginHostState.","commonSituations":"Servers with very many plugins/players hitting wasmtime resource-table limits; a plugin holding stale player resources causing table collisions; internal state bugs after plugin reload.","solutions":["Check PluginHostState's resource table for leaks (players never removed) that exhaust table capacity.","Ensure player resources are removed/reclaimed on player disconnect and plugin unload.","Upgrade wasmtime if the failure stems from a known resource-table bug.","Replace .expect with graceful error handling that skips plugin delivery instead of panicking the host."],"exampleFix":"// before\nlet player_res = state.add_player(self.player.clone())\n    .expect(\"failed to add player resource\");\n// after\nlet player_res = state.add_player(self.player.clone())\n    .map_err(|e| { log::error!(\"add_player failed: {e}\"); e })?;","handlingStrategy":"try-catch","validationCode":"// before dispatching the event to plugins\nif state.resource_table_size() >= state.resource_table_limit() {\n    skip_plugin_delivery();\n}","typeGuard":"fn player_resource_addable(state: &PluginHostState, player: &Arc<Player>) -> bool {\n    !state.contains_player(player) && state.resource_table_size() < state.resource_table_limit()\n}","tryCatchPattern":"match state.add_player(self.player.clone()) {\n    Ok(res) => res,\n    Err(e) => { log::error!(\"add_player failed: {e}\"); return; }\n}","preventionTips":["Remove player resources from PluginHostState on disconnect and plugin unload","Monitor resource-table size under heavy player/plugin load","Keep wasmtime up to date","Avoid .expect on per-event hot paths; degrade gracefully"],"tags":["wasm","plugin","resource-table","panic"],"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-16T04:17:20.429Z"}