passbolt/passbolt_api · error · NotFoundException

The resource does not exist.

Error message

The resource does not exist.

What it means

This NotFoundException is raised by ResourceActionLogsFinder::_checkUserCanAccessResource when ResourcesTable::findView($uac, $resourceId) returns no row. findView filters resources by the requesting user's access rules, so an empty result means the resource is missing, soft-deleted, or invisible to that user; the finder refuses to return action logs for a resource the user cannot access.

Solutions

  1. Confirm the resource exists with an admin UAC or direct SQL (SELECT id, deleted FROM resources WHERE id = '<uuid>') before calling the finder.
  2. If the resource exists but the user lacks access, share the resource with the user/adjust permissions entries, or query with sufficient privileges.
  3. Validate that the id passed is actually a resource id (not a folder or user id) and is a valid UUID from the same environment.
  4. In tests, persist the resource (and its owner/permissions) before invoking find().
  5. Catch the NotFoundException in the controller/endpoint layer and map it to an HTTP 404 response.

Example fix

// before
$logs = $resourceActionLogsFinder->find($limitedUserUac, $resourceId); // user has no access -> NotFoundException
// after
$resource = $Resources->findView($uac->getId(), $resourceId)->first();
if ($resource === null) {
    // resolve access: share resource or use an authorized UAC
    throw new NotFoundException(__('The resource does not exist.'));
}
$logs = $resourceActionLogsFinder->find($uac, $resourceId);
Defensive patterns

Strategy: validation

Validate before calling

$resource = TableRegistry::getTableLocator()->get('Resources')
    ->findView($uac->getId(), $resourceId)->first();
if ($resource === null) {
    throw new Cake\Http\Exception\NotFoundException(__('The resource does not exist.'));
}

Type guard

function resourceIsVisible($resourcesTable, $uac, $resourceId): bool {
    return is_string($resourceId) && \Cake\Validation\Validation::uuid($resourceId)
        && $resourcesTable->findView($uac->getId(), $resourceId)->first() !== null;
}

Prevention

When it happens

Trigger: Calling ResourceActionLogsFinder::find() with a resource UUID that does not exist, an id from another environment, a deleted resource, or a resource the UAC user has no permission on (not shared with them, or non-admin user without access).

Common situations: Audit log endpoints called after a resource was deleted; lookups with a folder id mistakenly passed as a resource id; staging/production id mix-ups; tests that forget to persist the resource; querying as a user who is not a member of the resource's shared groups.

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/60bfcdbccc3b9355. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltEe/AuditLog/src/Utility/ResourceActionLogsFinder.php:177

            ],
        ]);
    }

    /**
     * Check if a given user has access to a resource.
     *
     * @param \App\Utility\UserAccessControl $uac user
     * @param string $resourceId resource id
     * @return Resource whether or not he has access to the resource
     */
    protected function _checkUserCanAccessResource(UserAccessControl $uac, string $resourceId): Resource
    {
        /** @var \App\Model\Table\ResourcesTable $Resource */
        $Resource = TableRegistry::getTableLocator()->get('Resources');
        /** @var Resource|null $resource */
        $resource = $Resource->findView($uac->getId(), $resourceId)->first();
        if (empty($resource)) {
            throw new NotFoundException(__('The resource does not exist.'));
        }

        return $resource;
    }

    /**
     * @inheritDoc
     */
    public function find(UserAccessControl $uac, string $entityId, ?array $options = []): Query
    {
        // Check that user can access to resource.
        $this->_checkUserCanAccessResource($uac, $entityId);

        // Build query.
        $q = $this->_getBaseQuery();

        return $this->_filterQueryByResourceId($q, $entityId);
    }

View on GitHub (pinned to 31c1bbc10f)