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

Invalid schema for SCIM PATCH REQUEST

Error message

Invalid schema for SCIM PATCH REQUEST

What it means

A SCIM PATCH request must declare its schema via a 'schemas' array containing the patch-operation schema identifier (SchemaIdentifier::API_PATCH_OPERATION, urn:ietf:params:scim:api:messages:2.0:PatchOp). validateScimData throws this BadRequestException when the identifier is missing from the payload's schemas, indicating the request is not a conformant SCIM PATCH message.

Solutions

  1. Add "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"] to the PATCH request body.
  2. Verify the exact URN expected by SchemaIdentifier::API_PATCH_OPERATION in the plugin source.
  3. Check SchemaIdentifier for the identifier and align your client.
  4. Test the PATCH payload with a SCIM validator or curl against a known-good example.

Example fix

// before
{"Operations": [{"op": "replace", "path": "active", "value": true}]}
// after
{"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"], "Operations": [{"op": "replace", "path": "active", "value": true}]}
Defensive patterns

Strategy: validation

Validate before calling

const PATCH_SCHEMA = 'urn:ietf:params:scim:api:messages:2.0:PatchOp';
if (!in_array(PATCH_SCHEMA, $body['schemas'] ?? [], true)) {
    throw new InvalidArgumentException('PATCH body must declare the PatchOp schema URN');
}

Type guard

function hasPatchSchema(mixed $body): bool {
    return is_array($body)
        && in_array('urn:ietf:params:scim:api:messages:2.0:PatchOp', $body['schemas'] ?? [], true);
}

Try / catch

try {
    $patchRequest = PatchRequest::setFromScim($data);
} catch (BadRequestException $e) {
    // fix schemas envelope before retry
}

Prevention

When it happens

Trigger: PATCH /scim/v2/Users/{id} or /Groups/{id} with a body whose 'schemas' array omits the PatchOp URN, or has no 'schemas' key at all.

Common situations: Client sends a bare {'Operations': [...]} body without the schemas envelope; wrong URN copied from SCIM 1.1 docs; proxy/middleware strips or rewrites the body; custom integration omits metadata.

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

Appendix: source

Thrown at plugins/PassboltEe/Scim/src/Utility/Object/PatchRequest.php:62

        $this->operations = [];
        $operations = $data['Operations'] ?? [];
        foreach ((array)$operations as $operationData) {
            $this->operations[] = (new Operation())->setFromScim($operationData);
        }

        return $this;
    }

    /**
     * @param array $data
     * @return void
     */
    protected function validateScimData(array $data): void
    {
        $schemas = $data['schemas'] ?? [];
        if (!in_array(SchemaIdentifier::API_PATCH_OPERATION, $schemas)) {
            throw new BadRequestException('Invalid schema for SCIM PATCH REQUEST');
        }
        if (!array_key_exists('Operations', $data)) {
            throw new BadRequestException('Invalid data to create a SCIM PATCH REQUEST');
        }
    }

    /**
     * @inheritDoc
     */
    public function toSCIM(): array
    {
        $data = [
            'schemas' => [SchemaIdentifier::API_PATCH_OPERATION],
            'Operations' => [],
        ];
        foreach ($this->operations as $operation) {
            $data['Operations'][] = $operation->toSCIM();
        }

View on GitHub (pinned to 31c1bbc10f)