dani-garcia/vaultwarden · error
Grantee user should exist but does not!
Error message
Grantee user should exist but does not!
What it means
GET /emergency-access/{id} (grantor viewing details): the record is found for the grantor, then to_json_grantee_details() resolves the grantee user and the caller unwraps it with .expect("Grantee user should exist but does not!"). If the grantee account was deleted without cleaning the emergency_access row, this ordinary read endpoint panics (surfaced as a 500/connection reset) instead of returning a graceful error.
Source
Thrown at src/api/core/emergency_access.rs:96
emergency_access_list_json.push(ea.to_json_grantor_details(&conn).await);
}
Json(json!({
"data": emergency_access_list_json,
"object": "list",
"continuationToken": null
}))
}
#[get("/emergency-access/<emer_id>")]
async fn get_emergency_access(emer_id: EmergencyAccessId, headers: Headers, conn: DbConn) -> JsonResult {
check_emergency_access_enabled()?;
if let Some(emergency_access) =
EmergencyAccess::find_by_uuid_and_grantor_uuid(&emer_id, &headers.user.uuid, &conn).await
{
Ok(Json(
emergency_access.to_json_grantee_details(&conn).await.expect("Grantee user should exist but does not!"),
))
} else {
err!("Emergency access not valid.")
}
}
// endregion
// region put/post
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct EmergencyAccessUpdateData {
r#type: NumberOrString,
wait_time_days: i32,
key_encrypted: Option<String>,
}
View on GitHub (pinned to 0cefa4cca7)
Solutions
- Grantor deletes the orphaned entry via DELETE /emergency-access/{id} (which does not render grantee details)
- Or purge orphaned rows in the DB directly (back up first)
- Re-verify remaining emergency access entries afterwards
- Code fix: handle the None case with an err!() instead of expect
Example fix
// before
emergency_access.to_json_grantee_details(&conn).await.expect("Grantee user should exist but does not!")
// after
match emergency_access.to_json_grantee_details(&conn).await {
Some(details) => Ok(Json(details)),
None => err!("Grantee user for this emergency access no longer exists"),
} Defensive patterns
Strategy: validation
Validate before calling
-- Find emergency access rows whose grantee is missing before users hit the endpoint SELECT ea.uuid, ea.grantor_uuid, ea.grantee_uuid, ea.email FROM emergency_access ea LEFT JOIN users u ON u.uuid = ea.grantee_uuid WHERE ea.grantee_uuid IS NOT NULL AND u.uuid IS NULL;
Prevention
- Delete or decline emergency accesses before deleting user accounts
- Run the orphan-check query after user purges
- Back up before manual deletes on emergency_access
When it happens
Trigger: Grantor opens the emergency access details page or calls GET /emergency-access/{id} for an entry whose grantee user no longer exists — account deleted after invite/acceptance, or grantee_uuid/email dangling due to manual DB edits or partial restores.
Common situations: Admin-deleted or purged accounts with lingering emergency relationships; databases restored partially; compliance purges that remove users but not dependent rows.
Related errors
- Grantor user not found
- Grantee user not found
- Unable to update emergency access status
- Grantee user invalid
- Unable to update emergency access notification date
AI-assisted analysis of dani-garcia/vaultwarden@0cefa4cca7 (2026-08-16).
Data as JSON: /api/errors/4ab79f7df748500b.
Report an issue: GitHub.