Pumpkin-MC/Pumpkin · error · SpawnError
{message}
Error message
{message} What it means
`SpawnError` is the thiserror-based error type for task spawning in pumpkin-plugin-runtime; its `Display` simply renders the caller-supplied `message` string. Producers wrap whatever the underlying spawn failure was (runtime shut down, executor rejected the task, capacity limits) into this struct with a human-readable description.
Solutions
- Check whether the plugin/runtime is shutting down before spawning; abort pending work gracefully.
- Keep a valid, live runtime handle (clone it where needed) instead of spawning on a dropped executor.
- Log the `SpawnError`'s message to identify the underlying cause reported by the host.
- Retry only if the failure is transient (e.g. temporary overload); otherwise surface the error to the plugin caller.
Example fix
// before
runtime.spawn(work); // panics or loses error on shutdown
// after
if let Err(e) = runtime.spawn(work) {
log::error!("task not spawned: {e}");
} Defensive patterns
Strategy: try-catch
Validate before calling
// Check runtime liveness before spawning:
if shutting_down.load(Ordering::Acquire) { return; } Type guard
fn can_spawn(rt: &Option<RuntimeHandle>) -> bool { rt.is_some() } Try / catch
match runtime.spawn(work) {
Ok(fut) => { /* attach */ },
Err(e) => log::error!("spawn failed: {e}"),
} Prevention
- Track shutdown state and skip spawns during unload.
- Keep cloned runtime handles alive as long as the plugin may spawn.
- Log SpawnError messages to surface the host's underlying cause.
When it happens
Trigger: Any API in `pumpkin-plugin-runtime` that spawns a `SpawnFuture` fails — e.g. spawning on a runtime that has already been shut down, or a plugin host rejecting a spawn for policy/capacity reasons — and constructs `SpawnError { message }` with the detail.
Common situations: Plugins spawning background tasks during shutdown or world unload; spawning after the server runtime handle was dropped; host environments restricting async task creation for untrusted plugins.
Related errors
AI-assisted analysis of Pumpkin-MC/Pumpkin@8d4639e25a (2026-09-09).
Data as JSON: /api/errors/e4ce9404cdb2cd36.
Report an issue: GitHub.
Appendix: source
Thrown at crates/pumpkin-plugin-runtime/src/spawn.rs:8
use std::{future::Future, pin::Pin};
use thiserror::Error;
pub type SpawnFuture = Pin<Box<dyn Future<Output = ()> + Send + 'static>>;
#[derive(Clone, Debug, Error)]
#[error("{message}")]
pub struct SpawnError {
message: String,
}
impl SpawnError {
#[must_use]
pub fn new(message: impl Into<String>) -> Self {
Self {
message: message.into(),
}
}
}
/// Spawns runtime work without selecting or constructing an async runtime.
pub trait RuntimeSpawner: Send + Sync + 'static {
/// Transfers ownership of a future that must eventually be polled or
/// dropped when spawning succeeds.
fn spawn(&self, task: SpawnFuture) -> Result<(), SpawnError>;View on GitHub (pinned to 8d4639e25a)