dani-garcia/vaultwarden · error

Error loading groups

Error message

Error loading groups

What it means

Panic from `.expect()` on the Diesel `load` in `Group::find_by_organization`. The query listing all groups in an organization failed at the database layer, aborting the task. An org with zero groups returns an empty Vec; only genuine DB errors trigger this message.

Solutions

  1. Apply all pending migrations so the groups table exists
  2. Verify DB connectivity and DATABASE_URL credentials
  3. Check server logs for the underlying Diesel error
  4. Restore the groups table from backup if schema was manually altered

Example fix

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

Strategy: try-catch

Validate before calling

// verify groups table exists (schema supports groups feature)
// SELECT 1 FROM groups LIMIT 1;

Try / catch

// schema-gate before org group queries
if !schema_has_groups().await { return Vec::new(); }
Group::find_by_organization(org_uuid, conn).await

Prevention

When it happens

Trigger: Calling `Group::find_by_organization` with an unreachable DB, the `groups` table missing (pre-groups schema), or `organizations_uuid` column missing/renamed.

Common situations: Upgrading an old instance whose schema predates the groups feature without applying migrations; DB outage during an org management request; SQLite file locked.

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/2e1a5937109654d4. Report an issue: GitHub.

Appendix: source

Thrown at src/db/models/group.rs:202

                    .execute(conn)
                    .map_res("Error saving group")
            }
        }
    }

    pub async fn delete_all_by_organization(org_uuid: &OrganizationId, conn: &DbConn) -> EmptyResult {
        for group in Self::find_by_organization(org_uuid, conn).await {
            group.delete(org_uuid, conn).await?;
        }
        Ok(())
    }

    pub async fn find_by_organization(org_uuid: &OrganizationId, conn: &DbConn) -> Vec<Self> {
        conn.run(move |conn| {
            groups::table
                .filter(groups::organizations_uuid.eq(org_uuid))
                .load::<Self>(conn)
                .expect("Error loading groups")
        })
        .await
    }

    pub async fn count_by_org(org_uuid: &OrganizationId, conn: &DbConn) -> i64 {
        conn.run(move |conn| {
            groups::table.filter(groups::organizations_uuid.eq(org_uuid)).count().first::<i64>(conn).ok().unwrap_or(0)
        })
        .await
    }

    pub async fn find_by_uuid_and_org(uuid: &GroupId, org_uuid: &OrganizationId, conn: &DbConn) -> Option<Self> {
        conn.run(move |conn| {
            groups::table
                .filter(groups::uuid.eq(uuid))
                .filter(groups::organizations_uuid.eq(org_uuid))
                .first::<Self>(conn)
                .ok()

View on GitHub (pinned to cc67d644f6)