passbolt/passbolt_api · error · BadRequestException

The request id is invalid.

Error message

The request id is invalid.

What it means

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.

Solutions

  1. Confirm requestId is the AccountRecoveryRequest UUID returned by the start-requests endpoint.
  2. Check segment order in the URL: requestId comes first in the route.
  3. Validate the value client-side with a UUID regex before calling the endpoint.
  4. If the request was never created, call the start endpoint first to obtain a valid id.

Example fix

// before
const url = `/account-recovery/requests/${user.id}/${userId}/${tokenId}`;
// after
const url = `/account-recovery/requests/${requestId}/${userId}/${tokenId}`;
Defensive patterns

Strategy: validation

Validate before calling

const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
if (!requestId || !UUID_RE.test(requestId)) throw new Error('request id must be a UUID');

Type guard

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); }

Try / catch

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; } }

Prevention

When it happens

Trigger: GET /account-recovery/requests/<requestId>/<userId>/<tokenId> with requestId null, empty, or not a UUID.

Common situations: 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.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17). Data as JSON: /api/errors/532e3758ab589b1d. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltEe/AccountRecovery/src/Controller/AccountRecoveryRequests/AccountRecoveryRequestsGetController.php:62

     * Gets an account recovery request
     * Sends an email to the admins on suspect request
     *
     * @param string|null $requestId Request ID
     * @param string|null $userId User ID
     * @param string|null $tokenId Token ID
     * @return void
     * @throws \Cake\Http\Exception\BadRequestException if the data provided is not valid
     */
    public function get(?string $requestId, ?string $userId, ?string $tokenId): void
    {
        if (!isset($userId) || !Validation::uuid($userId)) {
            throw new BadRequestException(__('The user id is invalid.'));
        }
        if (!isset($tokenId) || !Validation::uuid($tokenId)) {
            throw new BadRequestException(__('The authentication token id is invalid.'));
        }
        if (!isset($requestId) || !Validation::uuid($requestId)) {
            throw new BadRequestException(__('The request id is invalid.'));
        }

        $ip = $this->getRequest()->clientIp();

        $service = new AccountRecoveryRequestGetService();
        $requestEntity = $service->getNotCompletedOrFail($requestId, $userId, $tokenId, $ip);
        $data = $service->decorateResults($requestEntity);

        $this->success(__('The operation was successful.'), $data);
    }
}

View on GitHub (pinned to 31c1bbc10f)