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

The filter for operator

Error message

The filter for operator `%s` is not supported yet

What it means

A SCIM list request contained a filter expression using an operator the SCIM plugin cannot translate into a database query. The filter parser supports a limited set of operators (e.g. eq, co, sw); any other operator (or an unsupported attribute/operator combination) hits the default case and throws this ScimException. It exists to fail fast instead of silently ignoring the filter and returning wrong results.

Solutions

  1. Inspect the filter attribute in the request URL and rewrite it using a supported operator (eq, co, sw as supported by the plugin).
  2. If the filter comes from an IdP, change the IdP provisioning/matching rule to use a supported filter (e.g. userName eq "...").
  3. Check ListResponse.php and ScimFilterParser to see which operators are implemented, and extend the match branches if you own the plugin code to add the needed operator.
  4. As a workaround, list without a filter and filter client-side.

Example fix

// before
GET /scim/v2/Users?filter=userName ne "jdoe"
// after
GET /scim/v2/Users?filter=userName eq "jdoe"
Defensive patterns

Strategy: validation

Validate before calling

// Before sending a SCIM list request
$allowed = ['eq', 'co', 'sw']; // operators supported by passbolt SCIM
$parsed = parseScimFilter($filter); // your client-side parser
if (!in_array($parsed->operator, $allowed, true)) {
    throw new InvalidArgumentException("Unsupported SCIM filter operator: {$parsed->operator}");
}

Try / catch

try {
    $resources = $scimClient->listUsers(['filter' => $filter]);
} catch (ScimException $e) {
    if (str_contains($e->getMessage(), 'is not supported yet')) {
        // fall back to unfiltered listing + client-side filtering
    }
}

Prevention

When it happens

Trigger: Calling GET /scim/v2/Users?filter=... or GET /scim/v2/Groups?filter=... via ScimFilterParser/SCIM list fetchResources with an operator like pr, ne, gt, lt, or a compound expression that the parser maps to an unsupported operator branch.

Common situations: An identity provider (Okta, Azure AD, JumpCloud) sends filters beyond passbolt's supported subset during user sync; a custom SCIM client hand-writes a filter string; a new IdP provisioning rule uses 'ne' or 'pr' on userName or externalId.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17). Data as JSON: /api/errors/c272818acdebb7f8. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltEe/Scim/src/Utility/Object/ListResponse.php:128

            $formattedFilter = str_replace('"', '', $formattedFilter);
            $filterParts = explode(' ', $formattedFilter);
            $attribute = $filterParts[0] ?? null;
            $operator = $filterParts[1] ?? null;
            $value = $filterParts[2] ?? null;
            switch (strtolower($operator)) {
                case 'eq':
                    switch ($attribute) {
                        case 'userName':
                            $conditions[$scimEntriesTable->aliasField('scim_name')] = $value;
                            break;
                        default:
                            throw new ScimException(
                                sprintf('The filter for attribute `%s` is not supported yet', $attribute)
                            );
                    }
                    break;
                default:
                    throw new ScimException(sprintf('The filter for operator `%s` is not supported yet', $operator));
            }
        }

        $countQuery = $scimEntriesTable->find();
        $this->resources = [];
        $result = $countQuery
            ->select(['count' => $countQuery->func()->count('id')])
            ->where($conditions)
            ->whereNull($scimEntriesTable->aliasField('deleted'))
            ->first();
        $this->totalResults = $result['count'] ?? 0;
        if ($this->totalResults === 0) {
            return $this;
        }

        /** @var array<\Passbolt\Scim\Model\Entity\ScimEntry> $scimResources */
        $scimResources = $scimEntriesTable
            ->find()

View on GitHub (pinned to 31c1bbc10f)