passbolt/passbolt_api · error · RuntimeException

A mapping rule for ID attribute could not be found for…

Error message

A mapping rule for ID attribute could not be found for directory type: {0}

What it means

DirectoryResults::_transformId resolves the LDAP attribute that uniquely identifies an object (user or group) from mappingRules[directoryType][objectType]['id']. When that mapping is absent it cannot determine the object's unique ID and throws, listing the directoryType.

Solutions

  1. Restore/refresh the default mapping rules by re-saving directory sync settings from the admin UI
  2. Confirm mappingRules[directoryType][objectType]['id'] is present (typically 'objectguid' for AD, 'entryuuid' for OpenLDAP)
  3. Check the LDAP entry's objectClass/directoryType attributes match what the configured mappings expect
  4. Extend the mapping rules for custom object classes in the directory settings

Example fix

// before
$idAttribute = $this->mappingRules[$directoryType][$type]['id'] ?? null;
if (!$idAttribute) {
    throw new RuntimeException(
        __('A mapping rule for ID attribute could not be found for directory type: {0}', $directoryType)
    );
}
// after
$idAttribute = $this->mappingRules[$directoryType][$type]['id'] ?? null;
if (!$idAttribute) {
    Log::warning("Missing id mapping for type={$type} directoryType={$directoryType}");
    throw new RuntimeException(
        __('A mapping rule for ID attribute could not be found for directory type: {0}', $directoryType)
    );
}
Defensive patterns

Strategy: validation

Validate before calling

$rules = $mappingRules[$directoryType][$objectType] ?? [];
if (empty($rules['id'])) { /* configure id mapping (objectguid/entryuuid) first */ }

Type guard

$idAttribute = $mappingRules[$directoryType][$objectType]['id'] ?? null;
if (!is_string($idAttribute) || $idAttribute === '') { return null; }

Try / catch

try {
    $entry = $results->transformLdapGroup($ldapGroup);
} catch (RuntimeException $e) {
    $this->log($e->getMessage()); // inspect directoryType/id mapping
}

Prevention

When it happens

Trigger: Calling transformLdapUser or transformLdapGroup for an object whose directoryType has no ['id'] rule for its objectType in the mapping rules array.

Common situations: Corrupted or hand-edited directory settings removing the 'id' mapping; LDAP entry with an objectClass the mappings do not cover (e.g. custom group class); directoryType attribute missing/renamed on the LDAP server so lookup keys mismatch.

Related errors


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

Appendix: source

Thrown at plugins/PassboltEe/DirectorySync/src/Utility/DirectoryEntry/DirectoryResults.php:272

        return $ldapUser;
    }

    /**
     * Adds a uuid to the ldap object if not present and if a dn exists.
     *
     * @param \LdapRecord\Models\Entry $ldapObject ldap object
     * @return \LdapRecord\Models\Entry ldap object
     * @throws \RuntimeException A mapping rule for ID attribute could not be found for the directory type
     */
    protected function _transformId(Entry $ldapObject): Entry
    {
        /** @var string $type */
        $type = $ldapObject->getFirstAttribute('objectType');
        /** @var string $directoryType */
        $directoryType = $ldapObject->getFirstAttribute('directoryType');
        $idAttribute = $this->mappingRules[$directoryType][$type]['id'] ?? null;
        if (!$idAttribute) {
            throw new RuntimeException(
                __('A mapping rule for ID attribute could not be found for directory type: {0}', $directoryType)
            );
        }
        $dn = $ldapObject->getDn();
        if (!$ldapObject->hasAttribute($idAttribute) && $dn) {
            /** @psalm-suppress InvalidArgument it takes args, not an array */
            $ldapObject->setAttribute($idAttribute, UuidFactory::uuid($dn));
        } else {
            $ldapObject->setAttribute($idAttribute, $ldapObject->getConvertedGuid());
        }

        return $ldapObject;
    }

    /**
     * Populate groups list from Ldap results.
     *
     * @return void

View on GitHub (pinned to 31c1bbc10f)