passbolt/passbolt_api · error · BadRequestException

The request data is invalid.

Error message

The request data is invalid.

What it means

BadRequestException thrown in MetadataPrivateKeysUpdateService::update when the request payload lacks a 'data' key or its value is not a string. The service validates input shape before touching the database. This guards against persisting malformed encrypted key payloads.

Solutions

  1. Ensure the request body contains a `data` key whose value is the encrypted payload as a plain string.
  2. If your client builds the payload as an object, serialize it to a string before sending.
  3. Log the outgoing request body and confirm `typeof data === 'string'` (or PHP is_string).

Example fix

// before
{"data": {"armored": "..."}}
// after
{"data": "{\"armored\": \"...\"}"}
Defensive patterns

Strategy: type-guard

Validate before calling

// JS
function isStringData(payload) {
  return payload != null && typeof payload.data === 'string' && payload.data.length > 0;
}
// PHP
if (!isset($data['data']) || !is_string($data['data'])) { /* fix payload */ }

Type guard

function hasStringData(p) { return typeof p === 'object' && p !== null && typeof p.data === 'string'; }

Try / catch

catch (BadRequestException) { // 400
  // inspect and fix the payload: data must be a string
}

Prevention

When it happens

Trigger: PUT to the metadata private key endpoint with body missing `data`, or `data` present as an object/array/null/number instead of a string (e.g. sending parsed JSON of the encrypted payload rather than its string form).

Common situations: Client libraries auto-decoding base64/JSON payloads before sending; forgetting to JSON-serialize the encrypted blob; copy-pasting request examples that use object payloads.

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

Appendix: source

Thrown at plugins/PassboltCe/Metadata/src/Service/MetadataPrivateKeysUpdateService.php:50

class MetadataPrivateKeysUpdateService
{
    use LocatorAwareTrait;

    /**
     * @param \App\Utility\UserAccessControl $uac user access control
     * @param string $privateKeyId uuid
     * @param array $data user provided data
     * @throws \Cake\Http\Exception\BadRequestException if the data is invalid
     * @throws \Cake\Http\Exception\NotFoundException if the record is not found or does not belong to the user
     * @throws \App\Error\Exception\ValidationException if the data does not validate
     * @throws \Cake\Http\Exception\InternalErrorException if data could not be saved because of an internal issue
     * @return \Passbolt\Metadata\Model\Entity\MetadataPrivateKey
     */
    public function update(UserAccessControl $uac, string $privateKeyId, array $data): MetadataPrivateKey
    {
        if (!isset($data['data']) || !is_string($data['data'])) {
            throw new BadRequestException(__('The request data is invalid.'));
        }
        if (!Validation::uuid($privateKeyId)) {
            throw new BadRequestException(__('The request data is invalid.'));
        }

        /** @var \Passbolt\Metadata\Model\Table\MetadataPrivateKeysTable $metadataPrivateKeysTable */
        $metadataPrivateKeysTable = $this->fetchTable('Passbolt/Metadata.MetadataPrivateKeys');
        try {
            /** @var \Passbolt\Metadata\Model\Entity\MetadataPrivateKey $metadataPrivateKey */
            $metadataPrivateKey = $metadataPrivateKeysTable
                ->find()
                ->where(['user_id' => $uac->getId(), 'id ' => $privateKeyId])
                ->firstOrFail();
        } catch (RecordNotFoundException $exception) {
            throw new NotFoundException(__('The metadata private key does not exist or has been deleted.'));
        }

        if ($metadataPrivateKey->modified_by === $uac->getId()) {

View on GitHub (pinned to 31c1bbc10f)