passbolt/passbolt_api · error · BadRequestException
The token is required in URL parameters.
Error message
The token is required in URL parameters.
What it means
The SSO success/recover-success callbacks require a 'token' query parameter that must pass OAuthTokenValidation::token() (a UUID-format check). Missing or malformed tokens are rejected with this 400 because the token identifies the verification/authentication token created in an earlier step.
Solutions
- Re-open the original link (from email or the client) intact, including the full token query parameter.
- Request a new SSO verification/recovery email or token — old tokens are single-use and may be expired.
- Verify the token is a complete UUID (no truncation) by inspecting the URL.
- If links keep breaking, check the email template / client that generates the URL for encoding issues (e.g. unescaped & splitting the query).
Defensive patterns
Strategy: validation
Validate before calling
const token = new URL(callbackUrl).searchParams.get('token');
const uuidRe = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
if (!uuidRe.test(token || '')) { throw new Error('Callback token missing or not a UUID'); } Type guard
function isValidToken(t) { return typeof t === 'string' && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(t); } Try / catch
try { await ssoSuccess(token); } catch (e) { if (e.status === 400 && /token is required/.test(e.message)) { requestNewVerificationToken(); } else { throw e; } } Prevention
- Open links from passbolt emails in full, without truncation
- Request fresh tokens — they are single-use and expire
- Check email/URL generation for encoding issues that break the query string
When it happens
Trigger: GET to ssoSuccess or ssoRecoverSuccess without ?token=..., or with a value that is not a valid UUID/token string (truncated link, tampered URL).
Common situations: Email clients or messaging apps truncating the callback URL at the token parameter; users hand-typing the URL; replaying an old link after the token was consumed/expired; copy-paste losing query parameters.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- The state is required in URL parameters.
- The code is required in request data.
- The code is required in URL parameters.
- The SSO authentication token is invalid. Settings id is…
- The SSO authentication token is invalid. User id mismatch.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/299db82d569f63c8.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/Sso/src/Controller/AbstractSsoController.php:122
$error = $this->getRequest()->getData('error');
$desc = $this->getRequest()->getData('error_description');
if (!is_string($error) || !is_string($desc)) {
return null;
} else {
return [$error => $desc];
}
}
/**
* @throws \Cake\Http\Exception\BadRequestException if the token is not provided in URL query
* @return string state
*/
public function getTokenFromUrlQuery(): string
{
$token = $this->request->getQuery('token');
if (!is_string($token) || !OAuthTokenValidation::token($token)) {
throw new BadRequestException(__('The token is required in URL parameters.'));
}
return $token;
}
/**
* @throws \Cake\Http\Exception\BadRequestException if the state is not provided in URL query
* @return string state
*/
public function getStateFromUrlQuery(): string
{
$state = $this->request->getQuery('state');
if (!is_string($state) || !SsoState::isValidState($state)) {
throw new BadRequestException(__('The state is required in URL parameters.'));
}
return $state;
}View on GitHub (pinned to 31c1bbc10f)