passbolt/passbolt_api · info · BadRequestException
The metadata session key data is identical.
Error message
The metadata session key data is identical.
What it means
No-op guard in MetadataSessionKeyUpdateService::update(): the submitted session key data is byte-identical to the stored record, so the update would change nothing and a conflict is raised rather than performing a redundant write.
Solutions
- Compute the new payload only when the underlying key/plaintext changed
- Check the existing value before calling update and skip if identical
- Treat this 400 as a no-op success in idempotent pipelines
Example fix
// before
$service->update($uac, $id, ['data' => $same, 'modified' => $modified]);
// after
if ($same !== $existing->get('data')) { $service->update($uac, $id, ['data' => $same, 'modified' => $modified]); } Defensive patterns
Strategy: validation
Validate before calling
if ($newData === $existingKey->get('data')) { return; } // skip no-op update Try / catch
try { $service->update($uac, $id, $data); } catch (BadRequestException $e) { /* identical data: treat as no-op */ } Prevention
- Compare payloads before sending updates
- Skip no-op writes in retry/cron logic
- Only rotate session keys when the underlying key material changes
When it happens
Trigger: Client re-sends the same encrypted payload without modification, or retries an already-applied update with identical content.
Common situations: Idempotent retry logic re-POSTing the same body, cron jobs refreshing keys unconditionally, generating the same armored message from unchanged plaintext.
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
- Could not validate the data.
- Invalid request. No policy change.
- The metadata key is already marked as expired.
- The metadata session key identifier should be a UUID.
- The metadata session key identifier should be a UUID.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/f33543627963a667.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltCe/Metadata/src/Service/MetadataSessionKeyUpdateService.php:80
$data = $form->getData();
/** @var \Passbolt\Metadata\Model\Table\MetadataSessionKeysTable $metadataSessionKeysTable */
$metadataSessionKeysTable = $this->fetchTable('Passbolt/Metadata.MetadataSessionKeys');
try {
/** @var \Passbolt\Metadata\Model\Entity\MetadataSessionKey $metadataSessionKey */
$metadataSessionKey = $metadataSessionKeysTable
->find()
->where(['id' => $id, 'user_id' => $uac->getId()])
->firstOrFail();
} catch (RecordNotFoundException $e) {
// 404 session key entry does not exist or not for current user_id
throw new NotFoundException(__('The metadata session key does not exist or does not belong to this user.'));
}
// 400 no changes to be made
if ($data['data'] === $metadataSessionKey->get('data')) {
throw new BadRequestException(__('The metadata session key data is identical.'));
}
// 409 if the modified date is not equal to the persisted session key one
$asserTime = (new DateTime($data['modified']))->diffInSeconds($metadataSessionKey->get('modified')) === 0;
if (!$asserTime) {
throw new ConflictException(__('The metadata session key data has changed.'));
}
$metadataSessionKey = $metadataSessionKeysTable->patchEntity(
$metadataSessionKey,
['data' => $data['data']],
['accessibleFields' => ['data' => true]]
);
try {
/** @var \Passbolt\Metadata\Model\Entity\MetadataSessionKey $updatedEntity */
$updatedEntity = $metadataSessionKeysTable->saveOrFail($metadataSessionKey);
} catch (PersistenceFailedException $exception) { // @phpstan-ignore-line
// 400 openpgp data does not validate, for example it's not for the current userView on GitHub (pinned to 31c1bbc10f)