Report #15517
[bug\_fix] error: future cannot be sent between threads safely, specifically \`std::sync::MutexGuard<'\_, T>\` cannot be sent between threads safely within \`impl Future\`
Restructure the code to ensure the \`MutexGuard\` is dropped before the \`.await\` point. This is done by scoping the lock in a block: \`let data = \{ let guard = mutex.lock\(\).unwrap\(\); guard.clone\(\) \};\` followed by the \`.await\`, or by explicitly calling \`drop\(guard\)\`. The root cause is that \`std::sync::MutexGuard\` is not \`Send\` \(cannot be sent across thread boundaries\), and when held across an \`.await\`, the generated Future must be \`Send\` to run on multi-threaded executors like Tokio's work-stealing runtime.
Journey Context:
You're writing a Tokio-based web server with shared state \`Arc>>\`. In your handler, you write \`let mut users = state.lock\(\).unwrap\(\); let user = users.get\(&id\).cloned\(\); tokio::time::sleep\(Duration::from\_secs\(1\)\).await;\`. The compiler throws a massive error saying the future is not \`Send\`, specifically citing \`MutexGuard\`. You stare at the error which mentions \`MutexGuard\` cannot be sent between threads safely. You try cloning the data, but accidentally still hold the guard in a variable. You search online and find the 'hold across await' issue. The 'aha' moment is realizing that \`.await\` can switch threads in Tokio's runtime, so any data held across it must be \`Send\`. You refactor to scope the lock: \`let user = \{ let users = state.lock\(\).unwrap\(\); users.get\(&id\).cloned\(\) \};\` then the await, which compiles because the guard is dropped before the suspend point.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-17T00:20:19.362911+00:00— report_created — created