passbolt/passbolt_api · warning · NotFoundException

The favorite does not exist.

Error message

The favorite does not exist.

What it means

FavoritesDeleteService::delete() looks up the favorite by its UUID with the Favorites table. When Table::get() finds no row it throws RecordNotFoundException, which is converted into this CakePHP NotFoundException (HTTP 404). It means no favorite exists with the given id (for the requesting user's visibility).

Solutions

  1. Verify the favorite id exists (GET the resource and check its favorite data) before calling delete
  2. Treat 404 as idempotent success if the goal is 'ensure not favorited' and swallow this error client-side
  3. Ensure the id passed is the favorite id, not the resource or user id

Example fix

// before
await deleteFavorite(someId);
// after
try {
  await deleteFavorite(someId);
} catch (e) {
  if (e.response?.status !== 404) throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

const isUuid = (v) => /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(v);
if (!isUuid(favoriteId)) throw new Error('invalid favorite id');

Type guard

const isUuid = (v: unknown): v is string =>
  typeof v === 'string' && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(v);

Try / catch

try {
  await api.delete(`/favorites/${favoriteId}`);
} catch (e) {
  if (e.response?.status === 404) return; // already deleted, idempotent
  throw e;
}

Prevention

When it happens

Trigger: Calling DELETE /favorites/{id} with an id that does not exist, was already deleted, or belongs to a favorite deleted in a prior request; also when the id is a valid UUID of a soft-deleted row.

Common situations: Client retries after a successful delete (double-tap), stale favorite ids cached in the UI after another user/resource removed them, or a race where two clients delete the same favorite concurrently.

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/98c0243c50fc0872. Report an issue: GitHub.

Appendix: source

Thrown at src/Service/Favorites/FavoritesDeleteService.php:57

    }

    /**
     * Unmarks a resource as favorite.
     *
     * @param string $id The identifier of favorite to delete.
     * @param string|null $userId Currently authenticated user's ID. Used to determine
     *                            if user can delete this favorite or not.
     * @return void
     * @throws \Cake\Http\Exception\NotFoundException When given ID doesn't exist.
     * @throws \Cake\Http\Exception\BadRequestException When unable to delete the entity.
     */
    public function delete(string $id, ?string $userId): void
    {
        // Retrieve the favorite.
        try {
            $favorite = $this->Favorites->get($id);
        } catch (RecordNotFoundException $e) {
            throw new NotFoundException(__('The favorite does not exist.'), 404, $e);
        }

        // Delete the favorite.
        $this->Favorites->delete($favorite, ['Favorites.user_id' => $userId]);
        $this->_handleDeleteErrors($favorite);
    }

    /**
     * Manage delete errors.
     *
     * @param \App\Model\Entity\Favorite $favorite Favorite entity.
     * @return void
     * @throws \Cake\Http\Exception\NotFoundException When user cannot delete this favorite entity.
     * @throws \Cake\Http\Exception\BadRequestException When unable to delete the entity.
     */
    private function _handleDeleteErrors(Favorite $favorite): void
    {
        $errors = $favorite->getErrors();

View on GitHub (pinned to 31c1bbc10f)