Report #91851
[bug\_fix] future cannot be sent between threads safely because \`Rc>\` cannot be sent between threads safely when using tokio::spawn
Replace \`Rc>\` with \`Arc>\` \(or \`std::sync::Mutex\` if contention is low\) to make the state thread-safe and \`Send\`. If the state must be thread-local, use \`tokio::task::LocalSet\` to spawn \`\!Send\` futures instead of \`tokio::spawn\`.
Journey Context:
Developer builds an async HTTP server using Axum. They need shared mutable state for a request counter. Accustomed to single-threaded Rust, they declare \`let counter = Rc::new\(RefCell::new\(0\)\);\` and clone it into a closure for the route handler. Inside the handler, they call \`counter.borrow\_mut\(\)\` and then \`.await\` on an external HTTP call. When they try to run the server, the compiler emits a massive error: \`future cannot be sent between threads safely\` because \`Rc>\` is not \`Send\`. Developer attempts to force \`Send\` by adding \`\+ Send\` bounds, which fails. They search the error and find explanations that \`Rc\` is for single-threaded reference counting and \`RefCell\` is not thread-safe. They refactor the code to use \`Arc::new\(tokio::sync::Mutex::new\(0\)\)\`. Inside the handler, they use \`\*counter.lock\(\).await \+= 1;\`. The code compiles and the server runs correctly across multiple threads.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T12:45:43.871135+00:00— report_created — created