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

  1. Re-open the original link (from email or the client) intact, including the full token query parameter.
  2. Request a new SSO verification/recovery email or token — old tokens are single-use and may be expired.
  3. Verify the token is a complete UUID (no truncation) by inspecting the URL.
  4. 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

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


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)