{"record":{"id":"1ef1c3c727e2f3dc","repo":"tokio-rs/tokio","slug":"background-task-failed","errorCode":null,"errorMessage":"background task failed","messagePattern":"background task failed","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"tokio/src/fs/file.rs","lineNumber":781,"sourceCode":"                    let seek = if !buf.is_empty() {\n                        Some(SeekFrom::Current(buf.discard_read()))\n                    } else {\n                        None\n                    };\n\n                    let n = buf.copy_from(src, me.max_buf_size);\n                    let std = me.std.clone();\n\n                    let res = spawn_mandatory_blocking(move || {\n                        let res = if let Some(seek) = seek {\n                            (&*std).seek(seek).and_then(|_| buf.write_to(&mut &*std))\n                        } else {\n                            buf.write_to(&mut &*std)\n                        };\n\n                        (Operation::Write(res), buf)\n                    })\n                    .ok_or_else(|| io::Error::new(io::ErrorKind::Other, \"background task failed\"));\n\n                    if res.is_err() {\n                        // Restore a valid Idle state before returning the error.\n                        inner.state = State::Idle(Some(Buf::with_capacity(0)));\n                    }\n                    let blocking_task_join_handle = res?;\n\n                    inner.state = State::Busy(blocking_task_join_handle);\n\n                    return Poll::Ready(Ok(n));\n                }\n                State::Busy(ref mut rx) => {\n                    let res = ready!(Pin::new(rx).poll(cx));\n                    if res.is_err() {\n                        // Restore a valid Idle state before returning the error.\n                        inner.state = State::Idle(Some(Buf::with_capacity(0)));\n                    }\n                    let (op, buf) = res?;","sourceCodeStart":763,"sourceCodeEnd":799,"githubUrl":"https://github.com/tokio-rs/tokio/blob/625954f365727668cb02d04172b34f1149637728/tokio/src/fs/file.rs#L763-L799","documentation":"Runtime error from `File::poll_write` (file.rs:781). The blocking write is dispatched via `spawn_mandatory_blocking`; if that returns `None` the runtime could not spawn the mandatory blocking task (runtime is shutting down or its blocking pool cannot accept it), and the write fails with `io::ErrorKind::Other`. The file restores a valid `Idle` state before returning.","triggerScenarios":"Issuing a `File` write while the Tokio runtime is shutting down, after the runtime context is gone, or when the mandatory blocking pool refuses the spawn. Occurs on the scalar `poll_write` path.","commonSituations":"Storing a `File` across runtime restarts; writing from a thread/task that outlives the runtime; dropping the runtime while file I/O is in flight; running `tokio::fs` operations outside any Tokio runtime.","solutions":["Ensure all `tokio::fs` I/O completes (is awaited) before the runtime is shut down.","Keep file operations inside a live runtime (`#[tokio::main]` or a manually driven runtime that outlives them).","Do not retain `File` handles across runtime teardown/recreation.","Handle `io::ErrorKind::Other` as a likely terminal/shutdown condition and propagate."],"exampleFix":"// before: file outlives the runtime\nlet file = tokio::fs::File::open(\"p\").await?;\n// ... runtime is dropped, then later:\nfile.write(&buf).await?; // 'background task failed'\n\n// after: keep the runtime alive for the whole file lifecycle\nasync fn run() -> io::Result<()> {\n    let mut file = tokio::fs::File::create(\"p\").await?;\n    file.write_all(&buf).await?;\n    file.flush().await?;\n    Ok(())\n} // all I/O resolves inside the live runtime","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"fn is_bg_task_failed(e: &io::Error) -> bool {\n    e.kind() == io::ErrorKind::Other && e.to_string() == \"background task failed\"\n}","tryCatchPattern":"if let Err(e) = file.write(&buf).await {\n    if is_bg_task_failed(&e) { return Err(anyhow!(\"runtime unavailable for file write (shutting down?)\")); }\n    return Err(e.into());\n}","preventionTips":["Keep all `tokio::fs` I/O inside a live runtime and await it before shutdown.","Do not let `File` handles outlive their runtime.","Model `background task failed` as terminal for that file/session."],"tags":["rust","tokio","fs","runtime","shutdown","blocking","runtime"],"backgroundTag":null,"analyzedSha":"625954f365727668cb02d04172b34f1149637728","analyzedAt":"2026-08-11T17:46:45.378Z","contentChangedAt":"2026-08-11T17:46:45.378Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}