Pumpkin-MC/Pumpkin · error
failed to add player resource
Error message
failed to add player resource
What it means
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.
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.
Example fix
// before
let player_res = state.add_player(self.player.clone())
.expect("failed to add player resource");
// after
let player_res = state.add_player(self.player.clone())
.map_err(|e| { log::error!("add_player failed: {e}"); e })?; Defensive patterns
Strategy: try-catch
Validate before calling
// before dispatching the event to plugins
if state.resource_table_size() >= state.resource_table_limit() {
skip_plugin_delivery();
} Type guard
fn player_resource_addable(state: &PluginHostState, player: &Arc<Player>) -> bool {
!state.contains_player(player) && state.resource_table_size() < state.resource_table_limit()
} Try / catch
match state.add_player(self.player.clone()) {
Ok(res) => res,
Err(e) => { log::error!("add_player failed: {e}"); return; }
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- failed to add world resource
- failed to add player resource
- failed to add world resource
- failed to add player resource
- failed to add world resource
AI-assisted analysis of Pumpkin-MC/Pumpkin@8d4639e25a (2026-09-09).
Data as JSON: /api/errors/d5039c6d40762a63.
Report an issue: GitHub.
Appendix: source
Thrown at crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/events/server.rs:33
},
},
server::{
list_ping::ServerListPingEvent,
map_initialize::MapInitializeEvent,
packet::{PacketReceivedEvent, PacketSentEvent},
server_broadcast::ServerBroadcastEvent,
server_command::ServerCommandEvent,
server_load::{LoadType, ServerLoadEvent},
server_tick_end::ServerTickEndEvent,
server_tick_start::ServerTickStartEvent,
},
};
impl ToFromWasmEvent for PacketReceivedEvent {
fn to_wasm_event(&self, state: &mut PluginHostState) -> Event {
let player_res = state
.add_player(self.player.clone())
.expect("failed to add player resource");
let packet = match self.player.client.as_ref() {
ClientPlatform::Java(client) => {
let version = client.version.load();
generated_packets::deserialize_java_serverbound_packet(
self.packet_id,
&self.payload,
version,
)
.map_or(ServerboundPacket::Unknown, ServerboundPacket::Java)
}
ClientPlatform::Bedrock(_) => {
generated_packets::deserialize_bedrock_serverbound_packet(
self.packet_id,
&self.payload,
)
.map_or(ServerboundPacket::Unknown, ServerboundPacket::Bedrock)
}View on GitHub (pinned to 8d4639e25a)