passbolt/passbolt_api · error · NotFoundException

The metadata key does not exist or has been deleted.

Error message

The metadata key does not exist or has been deleted.

What it means

Thrown when no metadata key row matches the given UUID: MetadataKeysTable::get() raises RecordNotFoundException, which the service converts to NotFoundException (HTTP 404). 'Deleted' is included because soft-deleted keys may also be filtered out.

Solutions

  1. List current keys via GET /metadata/keys and confirm the id exists
  2. Use the correct environment/database credentials
  3. Handle HTTP 404 in the caller and re-fetch the key list instead of retrying a stale id

Example fix

// before
await deleteMetadataKey(staleKeyId);
// after
const keys = await listMetadataKeys();
const key = keys.find(k => k.id === staleKeyId);
if (!key) throw new Error('key no longer exists');
await deleteMetadataKey(key.id);
Defensive patterns

Strategy: try-catch

Validate before calling

const key = (await listMetadataKeys()).find(k => k.id === id);
if (!key) throw new Error(`metadata key ${id} not found`);

Try / catch

try {
  await deleteMetadataKey(id);
} catch (e) {
  if (e.status === 404) refreshKeyCache(); else throw e;
}

Prevention

When it happens

Trigger: DELETE /metadata/keys/<valid-uuid> where the UUID does not exist, belongs to another environment/organization, or references an already soft-deleted key.

Common situations: Stale id cached from a previous database or a key deleted by another admin concurrently; pointing a script at a different environment (staging vs prod); DB was re-seeded or migrations recreated the table.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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

Appendix: source

Thrown at plugins/PassboltCe/Metadata/src/Service/MetadataKey/MetadataKeyDeleteService.php:61

     * @throws \Cake\Http\Exception\NotFoundException if the key does not exist or is already deleted
     * @throws \Cake\Http\Exception\BadRequestException if the key id format is Invalid or some items are still using the key
     */
    public function delete(UserAccessControl $uac, string $id): void
    {
        $uac->assertIsAdmin();

        if (!Validation::uuid($id)) {
            throw new BadRequestException(__('The metadata key ID should be a valid UUID.'));
        }

        $metadataKeysTable = $this->fetchTable('Passbolt/Metadata.MetadataKeys');

        // Assert the key exist
        try {
            /** @var \Passbolt\Metadata\Model\Entity\MetadataKey $metadataKey */
            $metadataKey = $metadataKeysTable->get($id);
        } catch (RecordNotFoundException $exception) { // @phpstan-ignore-line
            throw new NotFoundException(__('The metadata key does not exist or has been deleted.'), 404, $exception);
        }

        // Assert the key is not already deleted
        if ($metadataKey->isDeleted()) {
            throw new NotFoundException(__('The metadata key has already been deleted.'));
        }

        // Assert they key was previously marked as expired
        if (!$metadataKey->isExpired()) {
            throw new BadRequestException(__('The metadata key should be marked as expired first.'));
        }

        // Assert the key is not used by folders, resources, tags, etc.
        if ((new MetadataKeyAssertUsageService())->isKeyInUse($metadataKey->get('id'))) {
            $msg = __('The metadata key is still in use, migrate the remaining items to the new key first.');
            throw new BadRequestException($msg);
        }

View on GitHub (pinned to 31c1bbc10f)