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
- Send header 'Accept: application/json' with the request
- Send the GPGAuth challenge headers (X-GPGAuth-Version, X-GPGAuth-Login-URL, etc.) and a JSON body
- Ensure Content-Type is application/json for the request body
- 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
- Always send Accept: application/json and Content-Type: application/json to passbolt API endpoints
- Use the official passbolt SDK/CLI instead of hand-rolled requests
- Verify headers survive proxies
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
- This is not a valid Ajax/Json request.
- This is not a valid Ajax/Json request.
- Ajax/Json request not supported.
- Ajax/Json request not supported.
- Ajax/Json request not supported.
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)