passbolt/passbolt_api · error · BadRequestException
The authentication token id is invalid.
Error message
The authentication token id is invalid.
What it means
This BadRequestException is thrown by the account recovery request GET endpoint when the `tokenId` URL parameter is missing (null) or is not a valid UUID. The controller validates all route parameters up-front before delegating to the service layer, so a malformed token id never reaches the database lookup.
Solutions
- Verify the client calls the correct route order: /account-recovery/requests/{requestId}/{userId}/{tokenId}.
- Ensure the token id passed is the full UUID from the account recovery start response or email link.
- Check for null/empty query construction in the client SDK when the token is unavailable.
- Log the raw request URL server-side to confirm which segment is malformed.
Example fix
// before
await fetch(`/account-recovery/requests/${requestId}/${userId}`); // tokenId missing
// after
await fetch(`/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 (!tokenId || !UUID_RE.test(tokenId)) throw new Error('token 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 && /token id is invalid/.test(e.message)) { /* rebuild URL from stored token */ } else { throw e; } } Prevention
- Store the full token id from the recovery-start response and reuse it verbatim.
- Keep route segment order in a single shared URL builder.
- Validate all three UUIDs client-side before the call.
- Never hand-assemble recovery links from email text.
When it happens
Trigger: GET /account-recovery/requests/<requestId>/<userId>/<tokenId> called with tokenId null, empty, or not a UUID (e.g. truncated token, placeholder value, or wrong URL segment ordering).
Common situations: Clients building the recovery URL manually and swapping the userId/tokenId segments; older browser extensions or scripts written for a previous route signature; copy-paste of the link missing the last segment.
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.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Please provide a valid request id.
- The request id is invalid.
- The request id is invalid.
- The user identifier should be a valid UUID.
- $exception->getMessage() (dynamic, from wrapped…
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/540752308f73c777.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/AccountRecovery/src/Controller/AccountRecoveryRequests/AccountRecoveryRequestsGetController.php:59
}
/**
* 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)