{"record":{"id":"532e3758ab589b1d","repo":"passbolt/passbolt_api","slug":"the-request-id-is-invalid","errorCode":null,"errorMessage":"The request id is invalid.","messagePattern":"The request id is invalid\\.","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"plugins/PassboltEe/AccountRecovery/src/Controller/AccountRecoveryRequests/AccountRecoveryRequestsGetController.php","lineNumber":62,"sourceCode":"     * Gets an account recovery request\n     * Sends an email to the admins on suspect request\n     *\n     * @param string|null $requestId Request ID\n     * @param string|null $userId User ID\n     * @param string|null $tokenId Token ID\n     * @return void\n     * @throws \\Cake\\Http\\Exception\\BadRequestException if the data provided is not valid\n     */\n    public function get(?string $requestId, ?string $userId, ?string $tokenId): void\n    {\n        if (!isset($userId) || !Validation::uuid($userId)) {\n            throw new BadRequestException(__('The user id is invalid.'));\n        }\n        if (!isset($tokenId) || !Validation::uuid($tokenId)) {\n            throw new BadRequestException(__('The authentication token id is invalid.'));\n        }\n        if (!isset($requestId) || !Validation::uuid($requestId)) {\n            throw new BadRequestException(__('The request id is invalid.'));\n        }\n\n        $ip = $this->getRequest()->clientIp();\n\n        $service = new AccountRecoveryRequestGetService();\n        $requestEntity = $service->getNotCompletedOrFail($requestId, $userId, $tokenId, $ip);\n        $data = $service->decorateResults($requestEntity);\n\n        $this->success(__('The operation was successful.'), $data);\n    }\n}\n","sourceCodeStart":44,"sourceCodeEnd":74,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/AccountRecovery/src/Controller/AccountRecoveryRequests/AccountRecoveryRequestsGetController.php#L44-L74","documentation":"This BadRequestException is thrown when the `requestId` route parameter of the account recovery request GET endpoint is missing or fails UUID validation. Like the user/token checks, it fires before any service or database work, so the error always indicates a malformed client request rather than a missing record.","triggerScenarios":"GET /account-recovery/requests/<requestId>/<userId>/<tokenId> with requestId null, empty, or not a UUID.","commonSituations":"Client passes the user id where the request id belongs; link-building code uses the wrong response field; API version drift after route parameter changes.","solutions":["Confirm requestId is the AccountRecoveryRequest UUID returned by the start-requests endpoint.","Check segment order in the URL: requestId comes first in the route.","Validate the value client-side with a UUID regex before calling the endpoint.","If the request was never created, call the start endpoint first to obtain a valid id."],"exampleFix":"// before\nconst url = `/account-recovery/requests/${user.id}/${userId}/${tokenId}`;\n// after\nconst url = `/account-recovery/requests/${requestId}/${userId}/${tokenId}`;","handlingStrategy":"validation","validationCode":"const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nif (!requestId || !UUID_RE.test(requestId)) throw new Error('request id must be a UUID');","typeGuard":"function isValidUuid(v) { return typeof v === 'string' && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(v); }","tryCatchPattern":"try { await api.getAccountRecoveryRequest(requestId, userId, tokenId); } catch (e) { if (e.code === 400 && /request id is invalid/.test(e.message)) { requestId = await startRecoveryRequest(); } else { throw e; } }","preventionTips":["Keep requestId in a clearly named variable distinct from userId.","Create the request first (start endpoint) before polling it.","Validate UUID format before every call.","Add unit tests for URL builders."],"tags":["validation","uuid","bad-request","account-recovery"],"backgroundTag":"invalid-argument-format","analyzedSha":"31c1bbc10f32808a607fa9bd81891e898779c0bc","analyzedAt":"2026-09-17T00:04:38.960Z","contentChangedAt":"2026-09-17T00:04:38.960Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}