Report #76779
[bug\_fix] future cannot be sent between threads safely the trait \`Send\` is not implemented for \`std::sync::MutexGuard<'\_, T>\`
Restructure the code to drop the \`MutexGuard\` before the \`.await\` point by wrapping the critical section in a nested block scope \`\{ let guard = mutex.lock\(\).unwrap\(\); ... \}\`, or replace \`std::sync::Mutex\` with \`tokio::sync::Mutex\` which is designed to be held across await points and yields correctly without blocking the runtime.
Journey Context:
Developer writes an async fn that acquires a \`std::sync::MutexGuard\`, performs a quick calculation, then awaits an I/O operation \(like a database query or HTTP request\) while still holding the guard. The code compiles fine in unit tests using \`tokio::test\` with the single-threaded runtime, but fails in production with \`tokio::spawn\` and the multi-threaded runtime. The error points to the \`.await\` point, stating the future is not \`Send\` because the \`MutexGuard\` is \`\!Send\`. The developer tries wrapping the mutex in \`Arc\`, which doesn't help because the issue is the guard's lifetime across await points, not the mutex's shareability. They discover that \`std::sync::MutexGuard\` is platform-specific \(often tied to pthreads\) and cannot be sent across threads. The solution is either to scope the guard so it's dropped before the await, or switch to \`tokio::sync::Mutex\` which uses an async-aware locking strategy compatible with work-stealing runtimes.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-21T11:28:03.116239+00:00— report_created — created