{"record":{"id":"edfc68b67fdc2c8a","repo":"embassy-rs/embassy","slug":"spawntoken-instances-may-not-be-dropped-you-must","errorCode":null,"errorMessage":"SpawnToken instances may not be dropped. You must pass them to Spawner::spawn()","messagePattern":"SpawnToken instances may not be dropped\\. You must pass them to Spawner::spawn\\(\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"embassy-executor/src/spawner.rs","lineNumber":54,"sourceCode":"    }\n\n    /// Returns the task ID.\n    /// This can be used in combination with trace to match task names with IDs\n    pub fn id(&self) -> TaskId {\n        self.raw_task.id()\n    }\n\n    /// Get the metadata for this task. You can use this to set metadata fields\n    /// prior to spawning it.\n    pub fn metadata(&self) -> MetadataRef {\n        self.raw_task.metadata()\n    }\n}\n\nimpl<S> Drop for SpawnToken<S> {\n    fn drop(&mut self) {\n        // TODO deallocate the task instead.\n        panic!(\"SpawnToken instances may not be dropped. You must pass them to Spawner::spawn()\")\n    }\n}\n\n/// Error returned when spawning a task.\n#[derive(Copy, Clone)]\npub enum SpawnError {\n    /// Too many instances of this task are already running.\n    ///\n    /// By default, a task marked with `#[embassy_executor::task]` can only have one instance\n    /// running at a time. You may allow multiple instances to run in parallel with\n    /// `#[embassy_executor::task(pool_size = 4)]`, at the cost of higher RAM usage.\n    Busy,\n}\n\nimpl core::fmt::Debug for SpawnError {\n    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n        core::fmt::Display::fmt(self, f)\n    }","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/embassy-rs/embassy/blob/463a07b963419a1bfe61d5d597c44acb810afb8b/embassy-executor/src/spawner.rs#L36-L72","documentation":"Panic in SpawnToken's Drop impl: a SpawnToken carries ownership of a task's allocated state, and dropping it without spawning would leak that state permanently. The Drop impl therefore panics by design instead of silently leaking. It fires whenever a token returned by spawn-capable task methods (e.g. Spawner::spawn's argument-producing call sites, or make_spawn_token paths) is discarded — via unused result, early return between token creation and Spawner::spawn(), or wrapping the token in a scope that ends without spawning.","triggerScenarios":"Thrown at embassy-executor/src/spawner.rs:54 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Immediately pass every SpawnToken to Spawner::spawn() and don't store or discard it","Avoid early returns (?-operators, panics, matches) between token creation and spawn; bind the token right before spawning","Do not wrap SpawnToken in Option/Result that might drop it; spawn unconditionally","If conditional spawning is needed, only create the token after the condition is decided"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"463a07b963419a1bfe61d5d597c44acb810afb8b","analyzedAt":"2026-09-10T13:38:26.660Z","contentChangedAt":"2026-09-10T13:38:26.660Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}