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.


This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.