passbolt/passbolt_api · error · Passbolt\Scim\Exception\ResourceNotFoundException

The resource with id ` ` was not found

Error message

The %s resource with id `%s` was not found

What it means

After validating the UUID, setFromDatabase() looks up the user via Users->findForScim() (including deleted users) and, if no entity matches, throws ResourceNotFoundException with the SCIM resource type and the id that was requested. This mirrors SCIM's 404 semantics for GET/PUT/PATCH on nonexistent resources.

Solutions

  1. Verify the UUID exists: check the users table (SELECT id FROM users WHERE id = '...').
  2. If the user was legitimately deleted, have the IdP deprovision/remove its mapping instead of patching.
  3. Re-sync the IdP directory with current passbolt users to fix stale identifiers.
  4. If IDs came from another environment, use the correct environment's identifiers.
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check existence before PATCH/PUT
$user = $usersTable->find()->where(['id' => $uuid, 'deleted' => false])->first();
if (!$user) {
    throw new RuntimeException("User $uuid not found; skipping SCIM operation");
}

Try / catch

try {
    $resource->setFromDatabase($uuid);
} catch (ResourceNotFoundException $e) {
    // treat as 404: mark the IdP mapping as stale, skip or deprovision
}

Prevention

When it happens

Trigger: Calling setFromDatabase($id) where $id is a well-formed UUID that does not exist in the users table — e.g. PATCH/PUT /scim/v2/Users/{uuid} for a user already permanently removed or an id from another environment.

Common situations: Stale IdP directory referencing a user deleted on the passbolt side; ID from staging used in production; hard-delete vs soft-delete migrations cleaned the row; typos in stored mapping tables.

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/5577629cc816afc2. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltEe/Scim/src/Utility/Resource/UserScimResource.php:233

        }
    }

    /**
     * @inheritDoc
     */
    public function setFromDatabase(string $internalId): self
    {
        if (!Validation::uuid($internalId)) {
            throw new BadRequestException(__('The user identifier should be a valid UUID.'));
        }
        /** @var \App\Model\Entity\User|null $userEntity */
        $userEntity = $this->Users
            ->findForScim([$this->Users->aliasField('id') => $internalId], findDeleted: true)
            ->contain(['Profiles', 'ScimEntries'])
            ->first();
        $this->userEntity = $userEntity;
        if (!$this->userEntity) {
            throw new ResourceNotFoundException(
                sprintf('The %s resource with id `%s` was not found', $this->getType(), $internalId)
            );
        }
        if ($this->userEntity->deleted) {
            throw new ResourceNotFoundException(
                sprintf('The %s resource with id `%s` is already deleted', $this->getType(), $internalId)
            );
        }

        $this->id = $this->userEntity->id;
        $this->externalId = $this->userEntity->scim_entry?->external_identifier;
        $this->userName = $this->userEntity->scim_entry?->scim_name;
        $this->email = $this->userEntity->username;
        $this->firstName = $this->userEntity->profile?->first_name;
        $this->lastName = $this->userEntity->profile?->last_name;
        $this->active = !$this->userEntity->disabled;

        return $this;

View on GitHub (pinned to 31c1bbc10f)