passbolt/passbolt_api · warning · BadRequestException

This functionality is not available using AJAX/JSON.

Error message

This functionality is not available using AJAX/JSON.

What it means

Certain MFA flows (browser redirects to providers, Duo callbacks) cannot be consumed by AJAX/JSON clients because they return full HTML redirects. _assertRequestNotJson rejects JSON-type requests with a BadRequestException before any MFA logic runs.

Solutions

  1. Remove the .json extension and JSON headers from the request
  2. Use the JSON-specific endpoints guarded by _assertRequestIsJson instead
  3. Perform this flow in a browser context rather than via AJAX

Example fix

// before
await fetch('/mfa/verify/totp.json');
// after (non-json browser flow)
window.location.href = '/mfa/verify/totp';
Defensive patterns

Strategy: type-guard

Validate before calling

const isJsonRequest = url.endsWith('.json') || headers.Accept?.includes('application/json');
if (isJsonRequest) throw new Error('Use non-JSON browser flow for this endpoint');

Prevention

When it happens

Trigger: Requesting a non-JSON MFA endpoint (e.g. MFA verify GET/POST or Duo callback) with the .json extension or an Accept/Content-Type that marks the request as JSON.

Common situations: Calling the browser-oriented MFA verify page from a script or API client; frontend sending JSON headers to an endpoint designed for full-page redirects.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at plugins/PassboltCe/MultiFactorAuthentication/src/Controller/MfaController.php:83

     * Clear any dubious cookie if mfa check is required
     *
     * @return void
     */
    protected function _invalidateMfaCookie(): void
    {
        (new ClearMfaCookieInResponseService($this))->clearMfaCookie();
    }

    /**
     * Assert the request is not of json type.
     *
     * @return void
     * @throw BadRequestException if the request is of json type.
     */
    protected function _assertRequestNotJson(): void
    {
        if ($this->getRequest()->is('json')) {
            throw new BadRequestException(__('This functionality is not available using AJAX/JSON.'));
        }
    }

    /**
     * Assert the request is of json type.
     *
     * @return void
     * @throw BadRequestException if the request is not of json type.
     */
    protected function _assertRequestIsJson(): void
    {
        if (!$this->getRequest()->is('json')) {
            throw new BadRequestException(__('This functionality is only available using AJAX/JSON.'));
        }
    }
}

View on GitHub (pinned to 31c1bbc10f)