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
- Ensure the request body contains a `data` key whose value is the encrypted payload as a plain string.
- If your client builds the payload as an object, serialize it to a string before sending.
- 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
- Never auto-decode the encrypted payload before sending
- Always send `data` as a string
- Add a pre-send payload assertion in client tests
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
- Service provider missing.
- Service provider not supported.
- The data must be a string.
- The metadata private key could not be validated.
- The metadata session key could not be saved.
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)