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

The resource type ` ` is not valid

Error message

The resource type `%s` is not valid

What it means

ListResponse::fetchResources() first checks the resource type against ScimResources::isValid(); only 'Users' and 'Groups' are valid SCIM resource types in this implementation. Any other value in the SCIM list endpoint URL triggers a BadRequestException. This validates the /scim/v2/<type> path segment before any database work.

Solutions

  1. Use the exact resource types 'Users' and 'Groups' (capitalized) in the SCIM endpoint URL.
  2. Check the IdP's SCIM connector configuration and set the base endpoint correctly, e.g. https://passbolt.example.com/scim/v2/ with default user/group resource paths.
  3. Disable unsupported SCIM resource/sync features in the IdP connector if it requests types outside Users/Groups.

Example fix

// before
GET /scim/v2/users?filter=userName eq "ada"
// after
GET /scim/v2/Users?filter=userName eq "ada"
Defensive patterns

Strategy: validation

Validate before calling

const VALID = ['Users', 'Groups'];
if (!VALID.includes(resourceType)) {
  throw new Error(`SCIM resource type must be exactly one of ${VALID}, got: ${resourceType}`);
}

Type guard

const isScimResourceType = (t) => t === 'Users' || t === 'Groups';

Try / catch

try {
  const res = await fetch(`${base}/scim/v2/${resourceType}`);
  if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
} catch (e) {
  if (/resource type .* is not valid/.test(e.message)) console.error('Fix IdP connector endpoint paths to Users/Groups');
}

Prevention

When it happens

Trigger: GET /scim/v2/<resourceType> (list endpoint) where resourceType is not Users or Groups — e.g. /scim/v2/users (lowercase), /scim/v2/User, /scim/v2/Entitlements, or URL-encoding artifacts.

Common situations: IdP/SCIM clients (Azure AD/Entra, Okta) configured with a wrong base URL or supporting resource types this plugin doesn't implement (e.g. custom schemas); case-sensitivity bugs in client route building; proxies rewriting paths.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

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

    /**
     * Fetch resources based on the type, filter and pagination config
     *
     * @param string $resourceType
     * @param int|null $startIndex
     * @param int|null $count
     * @param string|null $filter
     * @return $this
     * @throws \Exception
     */
    public function fetchResources(
        string $resourceType,
        ?int $startIndex = null,
        ?int $count = null,
        ?string $filter = null,
    ) {
        if (!ScimResources::isValid($resourceType)) {
            throw new BadRequestException(sprintf('The resource type `%s` is not valid', $resourceType));
        }
        if (!isset(ScimEntry::MODEL_MAP[$resourceType])) {
            throw new BadRequestException(
                sprintf('The resource type `%s` has not map for scim entry model', $resourceType)
            );
        }

        if ($startIndex !== null && $startIndex > 0) {
            $this->startIndex = $startIndex;
        }
        if ($count !== null && $count > 0) {
            $this->itemsPerPage = $count;
        }

        /** @var \Passbolt\Scim\Model\Table\ScimEntriesTable $scimEntriesTable */
        $scimEntriesTable = $this->fetchTable('Passbolt/Scim.ScimEntries');
        $conditions = [
            $scimEntriesTable->aliasField('foreign_model') => ScimEntry::MODEL_MAP[$resourceType],

View on GitHub (pinned to 31c1bbc10f)