{"record":{"id":"c337cf9b037b8ce6","repo":"dani-garcia/vaultwarden","slug":"error-loading-devices","errorCode":null,"errorMessage":"Error loading devices","messagePattern":"Error loading devices","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/db/models/device.rs","lineNumber":206,"sourceCode":"                .first::<Self>(conn)\n                .ok()\n        })\n        .await\n    }\n\n    pub async fn find_with_auth_request_by_user(user_uuid: &UserId, conn: &DbConn) -> Vec<DeviceWithAuthRequest> {\n        let devices = Self::find_by_user(user_uuid, conn).await;\n        let mut result = Vec::new();\n        for device in devices {\n            let auth_request = AuthRequest::find_by_user_and_requested_device(user_uuid, &device.uuid, conn).await;\n            result.push(DeviceWithAuthRequest::from(device, auth_request));\n        }\n        result\n    }\n\n    pub async fn find_by_user(user_uuid: &UserId, conn: &DbConn) -> Vec<Self> {\n        conn.run(move |conn| {\n            devices::table.filter(devices::user_uuid.eq(user_uuid)).load::<Self>(conn).expect(\"Error loading devices\")\n        })\n        .await\n    }\n\n    pub async fn find_by_uuid(uuid: &DeviceId, conn: &DbConn) -> Option<Self> {\n        conn.run(move |conn| devices::table.filter(devices::uuid.eq(uuid)).first::<Self>(conn).ok()).await\n    }\n\n    pub async fn clear_push_token_by_uuid(uuid: &DeviceId, conn: &DbConn) -> EmptyResult {\n        conn.run(move |conn| {\n            diesel::update(devices::table)\n                .filter(devices::uuid.eq(uuid))\n                .set(devices::push_token.eq::<Option<String>>(None))\n                .execute(conn)\n                .map_res(\"Error removing push token\")\n        })\n        .await\n    }","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/dani-garcia/vaultwarden/blob/cc67d644f62605cb46f4d16c4a2eed1a861cc8bb/src/db/models/device.rs#L188-L224","documentation":"Panic from an `.expect()` on a Diesel query in `Device::find_by_user`. The library considers any failure to load the `devices` rows for a user fatal and panics rather than returning an empty/failed result. It indicates a database-level failure (connectivity, schema mismatch), not simply that the user has no devices.","triggerScenarios":"Calling `Device::find_by_user` while the database is down or the connection was dropped, after a failed/partial migration that removed or renamed the `devices` table/columns, or with a corrupted database file.","commonSituations":"Upgrade applied without migrations completing; DB credentials changed in config; SQLite data.db moved or corrupted; MySQL/Postgres restarted and pool holds stale connections.","solutions":["Verify DATABASE_URL connectivity and that the `devices` table exists with the expected columns","Restart Vaultwarden to apply pending migrations and rebuild the connection pool","Read the underlying Diesel error in the logs just above the panic and address it (connection, missing column, permissions)","Check DB permissions for the configured user (SELECT on devices table)"],"exampleFix":"// before\n.load::<Self>(conn).expect(\"Error loading devices\")\n// after\n.load::<Self>(conn).map_err(|e| err!(DbError, \"Error loading devices: {e}\"))","handlingStrategy":"try-catch","validationCode":"// check the devices table is reachable first\n// SELECT 1 FROM devices LIMIT 1; — if this fails, skip device-dependent logic","typeGuard":null,"tryCatchPattern":"// Catch or convert to a 503-style error instead of surfacing a raw panic\nif let Err(e) = db_health_check() { return service_unavailable(e); }","preventionTips":["Run migrations before deploying new binary versions","Keep connection pool settings (DB_TIMEOUT) tuned to your DB","Restart the service after any database failover/restart","Verify the DB user has SELECT on the devices table"],"tags":["database","diesel","panic","rust"],"backgroundTag":"database-query-failed","analyzedSha":"cc67d644f62605cb46f4d16c4a2eed1a861cc8bb","analyzedAt":"2026-09-19T08:28:46.370Z","contentChangedAt":"2026-09-19T08:28:46.370Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}