passbolt/passbolt_api · error · BadRequestException

Ajax/Json request not supported.

Error message

Ajax/Json request not supported.

What it means

Thrown by HandleErrorController::handleError when the request is JSON/Ajax. This controller renders a user-facing HTML error page for failed SSO self-registration flows, so JSON requests are rejected with 400, mirroring the other success/error redirect endpoints.

Solutions

  1. Navigate to the error URL with a normal browser redirect (HTML), not via fetch/XHR
  2. Drop JSON Accept/Content-Type headers when testing with curl/Postman
  3. Handle the underlying self-registration error in the JSON API flow before redirecting to this page
  4. Return the browser directly to the URL the server produced (e.g. after failed SSO register callback)

Example fix

// before
fetch('/sso/self-registration/error?email=...') // JSON-marked XHR
// after
window.location.href = '/sso/self-registration/error?email=...'
Defensive patterns

Strategy: validation

Validate before calling

const isJsonRequest = (init) =>
  (init?.headers?.Accept || '').includes('application/json') ||
  (init?.headers?.['Content-Type'] || '').includes('application/json');
if (isJsonRequest(myInit)) throw new Error('Error page must be loaded via browser navigation.');

Prevention

When it happens

Trigger: Requesting the self-registration error-handling endpoint via fetch/XHR, curl with Accept: application/json, or any JSON-marked request instead of browser navigation.

Common situations: Frontend code intercepts the error redirect and performs it via XHR; developer tests the error page URL with JSON headers; monitoring bots request the endpoint with JSON Accept headers.

Related errors


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

Appendix: source

Thrown at plugins/PassboltEe/SsoRecover/src/Controller/SelfRegistration/HandleErrorController.php:43

class HandleErrorController extends AbstractSsoController
{
    /**
     * @inheritDoc
     */
    public function beforeFilter(EventInterface $event)
    {
        parent::beforeFilter($event);

        $this->Authentication->allowUnauthenticated(['handleError']);
    }

    /**
     * @return void
     */
    public function handleError(): void
    {
        if ($this->request->is('json')) {
            throw new BadRequestException(__('Ajax/Json request not supported.'));
        }

        $this->User->assertNotLoggedIn();

        $email = $this->request->getQuery('email');
        if (!is_string($email) || !EmailValidationRule::check($email)) {
            throw new BadRequestException(__('The email is required in URL parameters.'));
        }

        $this->set(['message' => __('The user does not exist.')]);

        $this
            ->viewBuilder()
            ->setLayout('default')
            ->setTemplatePath('SelfRegistration')
            ->setTemplate('handle_error');
    }
}

View on GitHub (pinned to 31c1bbc10f)