passbolt/passbolt_api · error · Cake\Http\Exception\BadRequestException

This is not a valid Ajax/Json request.

Error message

This is not a valid Ajax/Json request.

What it means

Thrown by JwtLoginController::loginPost when the incoming request is not detected as a JSON request. The JWT login endpoint only accepts JSON bodies (and expects the GPGAuth headers); any other content type is rejected with a 400.

Solutions

  1. Send header 'Accept: application/json' with the request
  2. Send the GPGAuth challenge headers (X-GPGAuth-Version, X-GPGAuth-Login-URL, etc.) and a JSON body
  3. Ensure Content-Type is application/json for the request body
  4. Use the official passbolt client/CLI which constructs the request correctly

Example fix

// before
curl -X POST https://passbolt.example.com/auth/jwt/login
// after
curl -X POST https://passbolt.example.com/auth/jwt/login \
  -H "Content-Type: application/json" -H "Accept: application/json" \
  -H "X-GPGAuth-Version: 1.3.0" ...
Defensive patterns

Strategy: validation

Validate before calling

if (!headers['Accept']?.includes('application/json')) headers['Accept'] = 'application/json';
headers['Content-Type'] = 'application/json';

Try / catch

try { const r = await fetch(url, opts); } catch (e) { if (String(e.body?.message).includes('not a valid Ajax/Json request')) retryWithJsonHeaders(); }

Prevention

When it happens

Trigger: POST to /auth/jwt/login without header 'Accept: application/json' (and/or without a JSON content type), e.g. form-encoded POST or a plain browser navigation.

Common situations: Calling the endpoint with curl without -H "Content-Type: application/json"; testing in a browser address bar; older HTTP clients that don't send Accept: application/json; proxies stripping headers.

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/c77792fa2a00acb8. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltCe/JwtAuthentication/src/Controller/JwtLoginController.php:55

    {
        $this->Authentication->allowUnauthenticated([
            'loginPost',
        ]);

        EventManager::instance()->on(new UpdateUserLastLoggedInListener());

        parent::beforeFilter($event);
    }

    /**
     * User login post action
     *
     * @return void
     */
    public function loginPost()
    {
        if (!$this->request->is('json')) {
            throw new BadRequestException(__('This is not a valid Ajax/Json request.'));
        }

        $result = $this->Authentication->getResult();
        if ($result->isValid()) {
            $challenge = $result->getData()['challenge'];
            $user = $result->getData()['user'];
            $uac = new UserAccessControl($user['role']['name'], $user['id']);
            UserAction::getInstance()->setUserAccessControl($uac);

            $event = new Event(UpdateUserLastLoggedInListener::EVENT_USER_LOGIN_SUCCESS, $this, ['user' => $user]);
            $this->getEventManager()->dispatch($event);

            $this->success(__('The authentication was a success.'), compact('challenge'));
        } else {
            $message = __('The authentication failed.') . ' ';
            switch ($result->getStatus()) {
                case Result::FAILURE_CREDENTIALS_MISSING:
                    $message .= __('The credentials are missing.');

View on GitHub (pinned to 31c1bbc10f)