Getting: error[E0382]: use of moved value: `shared_pool`

Getting getting:

error[E0382]: use of moved value: `shared_pool`
  --> src/
43 |     let shared_pool = Arc::new(pool);
   |         ----------- move occurs because `shared_pool` has type `Arc<Pool<Postgres>>`, which does not implement the `Copy` trait
47 |     .route("/api/todos", get(move || get_todos(shared_pool.clone())))
   |                              -------           ----------- variable moved due to use in closure
   |                              |
   |                              value moved into closure here
51 |     .route("/api/todo/delete/:id", delete(move |path: Path<i32>| {
   |                                           ^^^^^^^^^^^^^^^^^^^^^^ value used here after move
52 |         // let pool_clone = Arc::clone(&shared_pool);
53 |         delete_todo(path, shared_pool.clone())
   |                           ----------- use occurs due to use in closure

For more information about this error, try `rustc --explain E0382`.
warning: `todo` (bin "todo") generated 8 warnings
error: could not compile `todo` due to previous error; 8 warnings emitted

Here is my

use std::sync::{Arc, Mutex};

use axum::{
     routing::{get, post, put, delete},  Json, Router, middleware::AddExtension, Extension, extract::Path

mod db;
use db::create_db_pool;

mod handlers;
use handlers::{get_todos, create_todo,delete_todo, root};

mod model;
use model::NewTodo;

async fn main() {
    let pool = create_db_pool().await;
    let pool_clone = pool.clone(); 
    let editPool = pool.clone();

    let shared_pool = Arc::new(pool);

    let app = Router::new()
    .route("/", get(root))
    .route("/api/todos", get(move || get_todos(shared_pool.clone())))
    .route("/api/todo/create", post(move |Json(new_todo): Json<NewTodo>| {
    .route("/api/todo/delete/:id", delete(move |path: Path<i32>| {
        // let pool_clone = Arc::clone(&shared_pool);
        delete_todo(path, shared_pool.clone())
    // .route("/api/todo/delete/:id", delete(delete_todo));
    // .layer(Extension( shared_pool));



    println!("🚀 Server started successfully");

and my delete handler is :


pub async fn create_todo(Json(new_todo): Json<NewTodo>, pool: PgPool) -> impl IntoResponse {
    let title = new_todo.title;
    let description = new_todo.description;
    let completed = new_todo.completed;

    let query_result = query!(
        INSERT INTO todo_items (title, description, completed)
        VALUES ($1, $2, $3)
        RETURNING *",

    match query_result {
        Ok(row) => {
            let new_id =;
                "status": "success",
                "message": "Todo created successfully",
                "new_id": new_id
        Err(_) => {
            // Handle error case
            // You can return an error response or customize it as needed
            // For now, let's return a generic error response
                "status": "error",
                "message": "Failed to create todo"

// #[axum_macros::debug_handler] 
pub async fn delete_todo(
    Path(id): Path<i32>, 
    pool: Arc<PgPool>
// Extension(db_pool): Extension<Arc<Mutex<PgPool>>>
) -> impl IntoResponse {
    println!("delete_todo id = {}", id);

    // Use the id to delete the item from the database
    let delete_result = query!(
        "DELETE FROM todo_items WHERE id = $1",

    if delete_result.is_ok() {
        // Return a success response
            "status": "success",
            "message": format!("Todo item with ID {} deleted", id)
    } else {
        // Return an error response
            "status": "error",
            "message": format!("Failed to delete todo item with ID {}", id)

You need to clone before moving the value and move the clone instead. I.e.

let shared_pool = Arc::new(pool);

let pool_for_todos = shared_pool.clone();

route("/api/todos", get(move || get_todos(pool_for_todos)));

That fixed it. Thank you.

1 Like

By the way, some people prefer writing cloning Arcs as Arc::clone(&shared_pool) instead, because Arc is a smart pointer where (unlike .clone()) most method calls will dereference to call a method on the pointed-to value, so readers might get confused believing the contents got cloned. Arc's own inherent method follow this convention of all not taking a self argument, so that as much of the method namespace is left open for the target types to use.