passbolt/passbolt_api · error · Cake\Datasource\Exception\RecordNotFoundException

The commented object type does not exist.

Error message

The commented object type does not exist.

What it means

CommentsTable::findViewForeignComments() retrieves the commented foreign object (e.g. a resource) first. If no record is found for the given user and foreign key, it throws RecordNotFoundException with this message.

Solutions

  1. Verify the resource id (foreignKey) exists and is not deleted before fetching comments.
  2. Check the user has access permission to the resource.
  3. Catch RecordNotFoundException and return 404 to the client.
  4. If ids are provided by clients, validate them against the resource table first.

Example fix

// before
$comments = $this->Comments->findViewForeignComments($userId, 'Resource', $resourceId);
// after
try { $comments = $this->Comments->findViewForeignComments($userId, 'Resource', $resourceId); }
catch (RecordNotFoundException $e) { throw new NotFoundException(__('The resource does not exist.')); }
Defensive patterns

Strategy: try-catch

Validate before calling

$resourcesTable = TableRegistry::getTableLocator()->get('Resources');
if (!$resourcesTable->findView($userId, $foreignKey)->first()) {
  throw new NotFoundException('Resource not found or not accessible.');
}

Try / catch

try { $comments = $commentsTable->findViewForeignComments($userId, 'Resource', $resourceId); }
catch (RecordNotFoundException $e) {
  throw new NotFoundException(__('The commented resource does not exist.'));
}

Prevention

When it happens

Trigger: Requesting comments for a foreignModel/foreignKey combination where the underlying resource does not exist, is soft-deleted, or the user lacks permission so findView() returns no row.

Common situations: Commenting endpoints called with a stale or deleted resource id, sharing permissions revoked so the user can no longer see the resource, or a wrong foreign key passed by a client.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — 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/2acec9be5ce2f644. Report an issue: GitHub.

Appendix: source

Thrown at src/Model/Table/CommentsTable.php:274

        ?array $options = []
    ): SelectQuery {
        // Check model sanity.
        if (!in_array($foreignModelName, self::ALLOWED_FOREIGN_MODELS)) {
            throw new InvalidArgumentException('The parameter foreignModel provided is not supported');
        }

        // Check uuid format.
        if (!Validation::uuid($foreignKey)) {
            throw new InvalidArgumentException('The parameter groupId should be a valid UUID.');
        }

        // Retrieve the resource.
        // This will break if the resource doesn't exist, if it is soft deleted, or if the user is not allowed to access it.
        /** @var \App\Model\Table\ResourcesTable $ResourcesTable */
        $ResourcesTable = TableRegistry::getTableLocator()->get('Resources');
        $foreignModelLookup = $ResourcesTable->findView($userId, $foreignKey)->first();
        if (empty($foreignModelLookup)) {
            throw new RecordNotFoundException(__('The commented object type does not exist.'));
        }

        $query = $this->find('threaded');
        $query->where([
            'Comments.foreign_model' => $foreignModelName,
            'Comments.foreign_key' => $foreignKey,
        ]);
        $query->orderBy([
            'Comments.modified' => 'DESC',
        ]);

        // If contains creator.
        if (isset($options['contain']['creator'])) {
            $query->contain([
                'Creator' => ['Profiles' => AvatarsTable::addContainAvatar()],
            ]);
        }

View on GitHub (pinned to 31c1bbc10f)