passbolt/passbolt_api · error · BadRequestException

Account recovery reason not supported.

Error message

Account recovery reason not supported.

What it means

Thrown by UserRecoverService::assertRecoveryCase when the 'case' field is a string but is not one of the values in ACCOUNT_RECOVERY_CASES. Only specific recovery reasons ('default', 'lost-token', etc.) are accepted; any other string is rejected with this message.

Solutions

  1. Check the exact allowed values in UserRecoverService::ACCOUNT_RECOVERY_CASES and send one verbatim.
  2. Fix typos — values are exact string matches, e.g. "lost-token" not "lost token".
  3. If you don't need a specific case, omit the field (defaults are applied).
  4. Verify your passbolt version supports the case you're sending (Pro-only or newer-release cases are rejected on older/CE servers).

Example fix

// before
{"username":"u@x.com","case":"password-reset"}

// after
{"username":"u@x.com","case":"lost-token"}
Defensive patterns

Strategy: validation

Validate before calling

const ALLOWED_CASES = ['default', 'lost-token', 'lost-passphrase', 'mfa-reset']; // per your server version's ACCOUNT_RECOVERY_CASES
if (body.case !== undefined && !ALLOWED_CASES.includes(body.case)) {
  throw new Error(`Unsupported recovery case: ${body.case}`);
}

Try / catch

try {
  await recover(body);
} catch (e) {
  if (e.response?.body?.message?.includes('reason not supported')) {
    console.error(`Unknown case "${body.case}"; use one of the documented values or omit it.`);
  }
}

Prevention

When it happens

Trigger: POST /recover.json with {"username": "u@x.com", "case": "forgot-password"} or any misspelled/unimplemented case value.

Common situations: Typos in the case value (e.g. 'lostpassword' vs 'lost-token'); API version drift where a case name was renamed or added in a newer passbolt version; docs from a different version or from the Pro edition listing cases unavailable in CE.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at src/Service/Users/UserRecoverService.php:140

            ->setLayout('default')
            ->setTemplate('triage');
    }

    /**
     * @return string self::ACCOUNT_RECOVERY_CASE_DEFAULT default
     */
    protected function assertRecoveryCase(): string
    {
        $case = $this->request->getData('case') ?? null;

        if (!isset($case)) {
            return self::ACCOUNT_RECOVERY_CASE_DEFAULT;
        }
        if (!is_string($case)) {
            throw new BadRequestException(__('Account recovery case must be a string.'));
        }
        if (!in_array($case, self::ACCOUNT_RECOVERY_CASES)) {
            throw new BadRequestException(__('Account recovery reason not supported.'));
        }

        return $case;
    }

    /**
     * Assert some username data is provided
     *
     * @throws \Cake\Http\Exception\BadRequestException if the username is not valid
     * @throws \Cake\Http\Exception\BadRequestException if the username is not provided
     * @return string validated username
     */
    protected function assertUsername(): string
    {
        $username = $this->request->getData('username') ?? null;
        if (!isset($username) || !is_string($username) || !EmailValidationRule::check($username)) {
            throw new BadRequestException(__('Please provide a valid email address.'));
        }

View on GitHub (pinned to 31c1bbc10f)