dani-garcia/vaultwarden · error

Error loading folders

Error message

Error loading folders

What it means

Panic from `.expect()` on the Diesel `load` in `Folder::find_by_user`. The query listing all folders for a user failed at the database layer, aborting the task. A user with no folders returns an empty Vec normally; only actual DB errors reach this expect.

Solutions

  1. Check DB connectivity and DATABASE_URL configuration
  2. Run pending migrations so the folders table matches the code
  3. Read the underlying Diesel error from server logs
  4. Fix file permissions/locks if running SQLite

Example fix

// before
.load::<Self>(conn).expect("Error loading folders")
// after
.load::<Self>(conn).unwrap_or_else(|e| { error!("load folders failed: {e}"); Vec::new() })
Defensive patterns

Strategy: try-catch

Validate before calling

// check the user exists and DB is reachable before listing folders
if !db_ping().await { return Vec::new(); }

Try / catch

// treat panic as service failure; pre-gate with health check
if !conn_ready(&conn).await { return Vec::new(); }
Folder::find_by_user(user_uuid, &conn).await

Prevention

When it happens

Trigger: Calling `Folder::find_by_user` while the DB is unreachable, the `folders` table or its columns are missing/renamed, or the connection errors mid-query.

Common situations: Schema drift after an upgrade without migrations; database restart or network blip during a sync request; SQLite file permission/lock issues; pool exhausted under heavy concurrent syncs.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


AI-assisted analysis of dani-garcia/vaultwarden@cc67d644f6 (2026-09-19). Data as JSON: /api/errors/4fcba35d77e2694f. Report an issue: GitHub.

Appendix: source

Thrown at src/db/models/folder.rs:133

            folder.delete(conn).await?;
        }
        Ok(())
    }

    pub async fn find_by_uuid_and_user(uuid: &FolderId, user_uuid: &UserId, conn: &DbConn) -> Option<Self> {
        conn.run(move |conn| {
            folders::table
                .filter(folders::uuid.eq(uuid))
                .filter(folders::user_uuid.eq(user_uuid))
                .first::<Self>(conn)
                .ok()
        })
        .await
    }

    pub async fn find_by_user(user_uuid: &UserId, conn: &DbConn) -> Vec<Self> {
        conn.run(move |conn| {
            folders::table.filter(folders::user_uuid.eq(user_uuid)).load::<Self>(conn).expect("Error loading folders")
        })
        .await
    }
}

impl FolderCipher {
    pub async fn save(&self, conn: &DbConn) -> EmptyResult {
        db_run! { conn:
            mysql {
                diesel::insert_into(folders_ciphers::table)
                    .values(self)
                    .on_conflict(diesel::dsl::DuplicatedKeys)
                    .do_nothing()
                    .execute(conn)
                    .map_res("Error adding cipher to folder")
            }
            postgresql, sqlite {
                diesel::insert_into(folders_ciphers::table)

View on GitHub (pinned to cc67d644f6)