{"record":{"id":"86b9655df34e7b3a","repo":"bitwarden/server","slug":"this-request-is-no-longer-valid-make-sure-to-appr","errorCode":null,"errorMessage":"This request is no longer valid. Make sure to approve the most recent request.","messagePattern":"This request is no longer valid\\. Make sure to approve the most recent request\\.","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"warning","filePath":"src/Api/Auth/Controllers/AuthRequestsController.cs","lineNumber":138,"sourceCode":"    {\n        // Get the current auth request to find the device identifier\n        var currentAuthRequest = await _authRequestService.GetAuthRequestAsync(id, userId);\n        if (currentAuthRequest == null)\n        {\n            throw new NotFoundException();\n        }\n\n        // Get all pending auth requests for this user (returns most recent per device)\n        var pendingRequests = await _authRequestRepository.GetManyPendingAuthRequestByUserId(userId);\n\n        // Find the most recent request for the same device\n        var mostRecentForDevice = pendingRequests\n            .FirstOrDefault(pendingRequest => pendingRequest.RequestDeviceIdentifier == currentAuthRequest.RequestDeviceIdentifier);\n\n        var isMostRecentRequestForDevice = mostRecentForDevice?.Id == id;\n        if (!isMostRecentRequestForDevice)\n        {\n            throw new BadRequestException(\"This request is no longer valid. Make sure to approve the most recent request.\");\n        }\n    }\n}\n","sourceCodeStart":120,"sourceCodeEnd":142,"githubUrl":"https://github.com/bitwarden/server/blob/e93b962371d80964556f5590c6615f5160a437a1/src/Api/Auth/Controllers/AuthRequestsController.cs#L120-L142","documentation":"Thrown as BadRequestException with a custom message (HTTP 400) from ValidateApprovalOfMostRecentAuthRequest, called by PUT /auth-requests/{id} when RequestApproved is true. After confirming the request exists, the method checks whether it is the most recent pending auth request for the same device (matched by RequestDeviceIdentifier). If a newer request exists for the same device, this older one is considered stale and cannot be approved.","triggerScenarios":"A device created multiple auth requests in sequence (e.g., the user repeatedly tapped 'approve login'). When the approving device tries to approve an older request, the server rejects it because only the most recent request per device is valid for approval.","commonSituations":"Requesting device sent multiple login requests rapidly, creating multiple pending entries for the same device identifier. Network retries on the requesting side created duplicate requests. User initiated login on the same device multiple times before approval. The approving device is acting on a notification for an older request while a newer one supersedes it.","solutions":["Call GET /auth-requests/pending to find the most recent request for the device and approve that one instead.","Ensure the approving device's UI refreshes the pending list before showing approve/deny buttons.","On the requesting side, avoid creating duplicate auth requests — cancel or wait before retrying."],"exampleFix":"// before: approving an older request that's been superseded\nvar resp = await client.PutAsJsonAsync($\"/auth-requests/{olderId}\",\n    new AuthRequestUpdateRequestModel { RequestApproved = true }); // 400\n\n// after: approve the most recent pending request for the device\nvar pending = await client.GetAsync(\"/auth-requests/pending\");\nvar mostRecent = pending.Items\n    .Where(r => r.RequestDeviceIdentifier == targetDevice)\n    .OrderByDescending(r => r.CreationDate)\n    .First();\nvar resp = await client.PutAsJsonAsync($\"/auth-requests/{mostRecent.Id}\",\n    new AuthRequestUpdateRequestModel { RequestApproved = true });","handlingStrategy":"validation","validationCode":"// Before approving, ensure this is the most recent request for the device\nvar pending = await client.GetAsync(\"/auth-requests/pending\");\nvar requestsForDevice = pending.Items\n    .Where(r => r.RequestDeviceIdentifier == targetDeviceIdentifier)\n    .OrderByDescending(r => r.CreationDate)\n    .ToList();\nif (requestsForDevice.Count == 0 || requestsForDevice[0].Id != idToApprove) {\n    var correctId = requestsForDevice[0]?.Id;\n    return Error($\"A newer request exists for this device. Approve request {correctId} instead.\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    var resp = await client.PutAsJsonAsync($\"/auth-requests/{id}\",\n        new AuthRequestUpdateRequestModel { RequestApproved = true });\n    resp.EnsureSuccessStatusCode();\n} catch (HttpRequestException ex) when (ex.StatusCode == HttpStatusCode.BadRequest) {\n    var body = await ex.Response.Content.ReadAsStringAsync();\n    if (body.Contains(\"most recent request\")) {\n        // Fetch the most recent pending request for this device and approve that\n        var pending = await client.GetAsync(\"/auth-requests/pending\");\n        var mostRecent = GetMostRecentForDevice(pending, deviceIdentifier);\n        resp = await client.PutAsJsonAsync($\"/auth-requests/{mostRecent.Id}\",\n            new AuthRequestUpdateRequestModel { RequestApproved = true });\n    }\n}","preventionTips":["On the requesting side, avoid creating duplicate auth requests for the same device — cancel or wait before retrying.","On the approving side, always fetch the latest pending list before presenting approve/deny options.","When multiple requests exist for the same device, approve the most recent one to avoid this error."],"tags":["auth-request","stale-request","device-approval","bad-request","concurrency"],"backgroundTag":null,"analyzedSha":"e93b962371d80964556f5590c6615f5160a437a1","analyzedAt":"2026-08-13T14:22:19.382Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}