passbolt/passbolt_api · error · BadRequestException

The code is required in request data.

Error message

The code is required in request data.

What it means

The POST-based SSO verification endpoints require a 'code' field in the request data (the authorization code or verify code). If it is unset or not a string, the controller throws this 400 because the subsequent state/token exchange cannot proceed.

Solutions

  1. Include the 'code' string field in the request body exactly as issued in the earlier step.
  2. Send the request with the correct Content-Type (application/json) so CakePHP parses the body into request data.
  3. Restart the SSO flow if the code was already consumed — get a fresh one from stage1.
  4. Upgrade/fix the client integration to the current SSO v2 payload schema.

Example fix

// before
fetch('/sso/verify', {method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify({state})});
// after
fetch('/sso/verify', {method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify({state, code: authCode})});
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof code !== 'string' || code.length === 0) { throw new Error('code must be a non-empty string before POSTing'); }
await fetch(url, {method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify({state, code})});

Type guard

function isNonEmptyString(v) { return typeof v === 'string' && v.length > 0; }

Try / catch

try { await api.post('/sso/verify', {state, code}); } catch (e) { if (e.status === 400 && /code is required in request data/.test(e.message)) { checkPayloadAndContentType(); } else { throw e; } }

Prevention

When it happens

Trigger: POST to an SSO endpoint that calls getCodeFromRequestData() with a body missing 'code', or where 'code' is not a string (null, object, number) — including bodies sent with the wrong Content-Type so the data does not parse.

Common situations: Client bug omitting the code field in the stage2 payload; JSON sent without Content-Type: application/json so getData() sees an empty array; legacy client versions using a different payload schema; proxy/gateway stripping the body.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at plugins/PassboltEe/Sso/src/Controller/AbstractSsoController.php:164

    public function getCodeFromUrlQuery(): string
    {
        $code = $this->request->getQuery('code');
        if (!isset($code) || !is_string($code)) {
            throw new BadRequestException(__('The code is required in URL parameters.'));
        }

        return $code;
    }

    /**
     * @throws \Cake\Http\Exception\BadRequestException if the code (access token) is not provided in request data
     * @return string code
     */
    public function getCodeFromRequestData(): string
    {
        $code = $this->getRequest()->getData('code');
        if (!isset($code) || !is_string($code)) {
            throw new BadRequestException(__('The code is required in request data.'));
        }

        return $code;
    }

    /**
     * @throws \Cake\Http\Exception\BadRequestException if the user_id is not provided in URL query
     * @return \App\Utility\ExtendedUserAccessControl
     */
    public function getUacFromData(): ExtendedUserAccessControl
    {
        $userId = $this->request->getData('user_id');
        if (!isset($userId) || !is_string($userId)) {
            throw new BadRequestException(__('The user id is required in URL parameters.'));
        }

        return $this->getUacFromUserIdAndRequest($userId);
    }

View on GitHub (pinned to 31c1bbc10f)