passbolt/passbolt_api · error · NotFoundException

The metadata session key does not exist or does not belong…

Error message

The metadata session key does not exist or does not belong to this user.

What it means

After UUID validation, delete() looks up the session key filtered by both id and user_id (ownership check). If no row matches, firstOrFail throws RecordNotFoundException which is converted to a 404 NotFoundException. The key either does not exist or belongs to another user.

Solutions

  1. Verify the id exists via the metadata session key index endpoint for the current user
  2. Check you are authenticated as the user who created the session key
  3. Handle the 404 gracefully and treat it as already-deleted in idempotent workflows
Defensive patterns

Strategy: try-catch

Validate before calling

$key = $table->find()->where(['id' => $id, 'user_id' => $uac->getId()])->first(); if (!$key) { return; } // pre-check before delete

Type guard

if ($key === null) { throw new NotFoundException(); }

Try / catch

try { $service->delete($uac, $id); } catch (NotFoundException $e) { /* treat as already deleted */ }

Prevention

When it happens

Trigger: DELETE call with a valid UUID id that (a) was never created, (b) was already deleted, or (c) belongs to a different user than the one in the UserAccessControl.

Common situations: Re-running cleanup scripts that delete twice, using an admin account to delete another user's session key (not allowed by design), stale client cache referencing an expired key.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

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

     * @return void
     */
    public function delete(UserAccessControl $uac, string $id): void
    {
        if (!Validation::uuid($id)) {
            throw new BadRequestException(__('The metadata session key identifier should be a UUID.'));
        }

        /** @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) {
            throw new NotFoundException(__('The metadata session key does not exist or does not belong to this user.')); // phpcs:ignore
        }

        if ($metadataSessionKeysTable->delete($metadataSessionKey)) {
            return;
        }

        // In scenarios where requests are sent twice delete can fail.
        // Check for the record again and if it doesn't exist then throw 404. If present and delete fail then throw a 500.
        $exists = $metadataSessionKeysTable
            ->find()
            ->select(['id'])
            ->where(['id' => $id, 'user_id' => $uac->getId()])
            ->first();

        $exists
            ? throw new InternalErrorException(__('The metadata session key could not be deleted.'))
            : throw new NotFoundException(__('The metadata session key does not exist or does not belong to this user.')); // phpcs:ignore
    }

View on GitHub (pinned to 31c1bbc10f)