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

Invalid request. New key or passwords are not required.

Error message

Invalid request. New key or passwords are not required.

What it means

This BadRequestException is thrown when an administrator tries to disable the account recovery organization policy while including a new organization public key or private key passwords in the request payload. Disabling recovery must be a clean operation: the current key is revoked, backups are truncated, and no replacement key material is accepted. The service rejects the request as invalid rather than silently ignoring the extra data.

Solutions

  1. Remove account_recovery_organization_public_key and account_recovery_private_key_passwords from the request payload when setting policy to 'disabled'.
  2. Send only the policy field: {"policy": "disabled"} (plus any required revocation fields handled elsewhere).
  3. If a client UI/library adds these fields automatically, update it or its serializer to strip key data on disable.
  4. Review the API docs for the disable flow: keys are revoked server-side, replacement data is never accepted.

Example fix

// before (disable with leftover key data)
await passbolt.updateAccountRecoveryOrganizationPolicy({
  policy: 'disabled',
  account_recovery_organization_public_key: armoredKey
});

// after (disable with minimal payload)
await passbolt.updateAccountRecoveryOrganizationPolicy({
  policy: 'disabled'
});
Defensive patterns

Strategy: validation

Validate before calling

const isDisabling = payload.policy === 'disabled';
if (isDisabling && (payload.account_recovery_organization_public_key || payload.account_recovery_private_key_passwords)) {
  throw new Error('Do not send new key or passwords when disabling account recovery.');
}

Type guard

function isDisablePayload(p) {
  return p.policy === 'disabled' &&
    p.account_recovery_organization_public_key === undefined &&
    p.account_recovery_private_key_passwords === undefined;
}

Try / catch

try {
  await passbolt.setAccountRecoveryOrganizationPolicy(payload);
} catch (e) {
  if (e.status === 400 && /New key or passwords are not required/.test(e.message)) {
    delete payload.account_recovery_organization_public_key;
    delete payload.account_recovery_private_key_passwords;
    return retry(payload);
  }
  throw e;
}

Prevention

When it happens

Trigger: POST/PUT to the account recovery organization settings endpoint with policy set to 'disabled' while the payload also contains 'account_recovery_organization_public_key' or 'account_recovery_private_key_passwords'. Occurs in AccountRecoveryOrganizationPolicySetService::set() at the isDisabling() branch.

Common situations: A client script or admin UI re-sends the previous payload (which included the public key) but changes only the policy field to 'disabled'; automation tooling that always includes the full settings object; API consumers copying the 'enable' request shape for the 'disable' call.

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

Appendix: source

Thrown at plugins/PassboltEe/AccountRecovery/src/Service/AccountRecoveryOrganizationPolicies/AccountRecoveryOrganizationPolicySetService.php:81

        // if disabled => enabled
        if ($this->isEnabling()) {
            // if public key is not provided
            if (!$isNewKeyProvided) {
                throw new BadRequestException(__('Invalid request. An organization recovery public key is required.'));
            }
            // if key revocation or passwords provided
            if ($isRevokedKeyProvided || $isPrivateKeyPasswordsProvided) {
                throw new BadRequestException(__('Invalid request. Revoked key or passwords are not required.'));
            }

            return $this->enablePolicy($uac, $newPolicy);
        }

        // if enabled => disabled
        if ($this->isDisabling()) {
            // if new key or passwords provided
            if ($isNewKeyProvided || $isPrivateKeyPasswordsProvided) {
                throw new BadRequestException(__('Invalid request. New key or passwords are not required.'));
            }

            // save new disabled policy, disable previous key and delete backups if any
            return $this->disablePolicy($uac);
        }

        // if enabled => enabled
        // e.g it's policy change like mandatory => opt-in
        // and/or a possible key rotation
        if (($isNewKeyProvided && !$isRevokedKeyProvided) || (!$isNewKeyProvided && $isRevokedKeyProvided)) {
            throw new BadRequestException(__('Invalid request. Keys are required for this change.'));
        }

        // if key provided or revocation provided
        $newKey = null;
        $oldKey = null;
        $passwords = null;
        /** @psalm-suppress RedundantCondition */

View on GitHub (pinned to 31c1bbc10f)