passbolt/passbolt_api · error · CustomValidationException

The metadata session key could not be saved.

Error message

The metadata session key could not be saved.

What it means

CustomValidationException thrown in MetadataSessionKeyCreateService::create when saveOrFail raises a PersistenceFailedException. The entity's validation errors are attached to the exception so the API can return them to the client. It covers all table-level rule failures for a new metadata session key.

Solutions

  1. Read the `errors` attribute of the exception response for the exact failing fields.
  2. Delete/deactivate any existing session key for the user before creating a new one if the rule forbids duplicates.
  3. Ensure `data` is a properly encrypted string per the metadata session key specification.

Example fix

// before: create without cleaning up old key
await api.post('/metadata/session-keys', {data});
// after
await api.delete(`/metadata/session-keys/${existingId}`);
await api.post('/metadata/session-keys', {data});
Defensive patterns

Strategy: validation

Validate before calling

const existing = await api.get('/metadata/session-keys');
if (existing.some(k => k.userId === currentUserId)) {
  throw new Error('session key already exists for user');
}

Try / catch

catch (CustomValidationException $e) {
  $errors = $e->getErrors();
  // handle duplicate/invalid fields accordingly
}

Prevention

When it happens

Trigger: POST creating a metadata session key where the entity fails validation: missing/invalid `data`, invalid user_id, or a custom rule (e.g. user already has an active session key).

Common situations: Duplicate session key for the same user when a previous one wasn't deleted; payload `data` not a valid encrypted string; schema constraint differences across MySQL/MariaDB/Postgres.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at plugins/PassboltCe/Metadata/src/Service/MetadataSessionKeyCreateService.php:54

     */
    public function create(UserAccessControl $uac, mixed $data): MetadataSessionKey
    {
        $this->assertData($data);

        /** @var \Passbolt\Metadata\Model\Table\MetadataSessionKeysTable $metadataSessionKeysTable */
        $metadataSessionKeysTable = $this->fetchTable('Passbolt/Metadata.MetadataSessionKeys');

        $metadataSessionKey = $metadataSessionKeysTable->newEntity(
            ['user_id' => $uac->getId(), 'data' => $data],
            ['accessibleFields' => ['user_id' => true, 'data' => true]]
        );
        try {
            /** @var \Passbolt\Metadata\Model\Entity\MetadataSessionKey $result */
            $result = $metadataSessionKeysTable->saveOrFail($metadataSessionKey);
        } catch (PersistenceFailedException $e) { // @phpstan-ignore-line
            $errors = $e->getEntity()->getErrors();

            throw new CustomValidationException(
                __('The metadata session key could not be saved.'),
                $errors
            );
        } catch (Exception $e) {
            throw new InternalErrorException(
                __('Could not save the metadata session key, please try again later.'),
                null,
                $e
            );
        }

        return $result;
    }

    /**
     * Basic sanity check for the given data value.
     *
     * @param mixed $data Data to check.

View on GitHub (pinned to 31c1bbc10f)