passbolt/passbolt_api · error · Cake\Http\Exception\BadRequestException

Invalid schema for SCIM User Resource

Error message

Invalid schema for SCIM User Resource

What it means

A SCIM User resource payload must declare the core user schema identifier (SchemaIdentifier::CORE_USER, urn:ietf:params:scim:schemas:core:2.0:User) in its 'schemas' array. validateScimUserData throws this BadRequestException when creating or updating a user (setFromScim/put) with a payload missing that identifier, ensuring passbolt only processes conformant User resources.

Solutions

  1. Include "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"] in the user payload.
  2. Check SchemaIdentifier::CORE_USER in the plugin for the exact expected URN.
  3. Fix the IdP/resource-type mapping so User provisioning payloads declare the core user schema.
  4. Capture the raw request body and diff it against a known-good SCIM User example.

Example fix

// before
{"userName": "jdoe@example.com", "name": {...}}
// after
{"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"], "userName": "jdoe@example.com", "name": {...}}
Defensive patterns

Strategy: validation

Validate before calling

const USER_SCHEMA = 'urn:ietf:params:scim:schemas:core:2.0:User';
if (!in_array(USER_SCHEMA, $body['schemas'] ?? [], true)) {
    throw new InvalidArgumentException('User payload must declare the core User schema URN');
}

Type guard

function hasCoreUserSchema(mixed $body): bool {
    return is_array($body)
        && in_array('urn:ietf:params:scim:schemas:core:2.0:User', $body['schemas'] ?? [], true);
}

Try / catch

try {
    $resource = UserScimResource::setFromScim($data);
} catch (BadRequestException $e) {
    // inject/repair the schemas array before retry
}

Prevention

When it happens

Trigger: POST /scim/v2/Users (create) or PUT /scim/v2/Users/{id} (replace) with a body whose 'schemas' lacks the core User URN or has no 'schemas' key.

Common situations: Client sends a Group schema or Enterprise user extension URN only; schemas key omitted in custom scripts; IdP misconfigured resource type mapping; SCIM 1.1 URN used instead of 2.0.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — 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/7efe2a11e036cb8e. Report an issue: GitHub.

Appendix: source

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

        $this->middleName = $data['name']['middleName'] ?? null;
        if (isset($data['active'])) {
            $this->active = (bool)$data['active'];
        }
        $emails = Hash::extract($data, 'emails.{n}[type=work].value');
        $this->email = $emails[0] ?? null;

        return $this;
    }

    /**
     * @param array $data
     * @return void
     */
    protected function validateScimUserData(array $data): void
    {
        $schemas = $data['schemas'] ?? [];
        if (!in_array(SchemaIdentifier::CORE_USER, $schemas)) {
            throw new BadRequestException('Invalid schema for SCIM User Resource');
        }
    }

    /**
     * @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) {

View on GitHub (pinned to 31c1bbc10f)