passbolt/passbolt_api · error · InvalidArgumentException

An error has occurred parsing enabledUsersOnly filter

Error message

An error has occurred parsing enabledUsersOnly filter: {pe->getMessage()}

What it means

_fetchAndInitializeUsersQuery() applies Active Directory's enabled-users LDAP filter using LdapRecord's filter Parser. If parsing or re-assembling the hard-coded AD_ENABLED_USERS_FILTER fails with a ParserException, the error is wrapped in an InvalidArgumentException carrying the parser's message. This indicates the LDAP filter string could not be parsed, which is normally only possible if the constant was overridden or an incompatible LdapRecord version is installed.

Solutions

  1. Read the wrapped ParserException message to identify the offending filter token.
  2. Verify the LdapRecord version matches passbolt's composer.lock requirements (`composer show ldaprecord/ldap` / `ddev composer install`) and reinstall vendor dependencies.
  3. Check no subclass redefines DirectoryInterface::AD_ENABLED_USERS_FILTER with invalid filter syntax; restore the original constant.
  4. As a workaround, disable the enabledUsersOnly setting and filter disabled accounts at sync-result level until the filter parses.

Example fix

// before (custom filter override)
const AD_ENABLED_USERS_FILTER = '(&(objectCategory=user)(!(userAccountControl:1.2.840.113556.1.4.803::=2)))';
// after (valid matching-rule syntax)
const AD_ENABLED_USERS_FILTER = '(&(objectCategory=person)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))';
Defensive patterns

Strategy: try-catch

Validate before calling

if ($directoryType === 'ad' && $enabledUsersOnly) {
    try { Parser::parse(DirectoryInterface::AD_ENABLED_USERS_FILTER); }
    catch (ParserException $pe) {
        Log::error('AD enabled-users filter invalid: ' . $pe->getMessage());
    }
}

Try / catch

try { $results = $ldapDirectory->getFilteredDirectoryResults(); } catch (InvalidArgumentException $e) {
    if (str_contains($e->getMessage(), 'enabledUsersOnly')) {
        Log::error('AD filter parse failed: ' . $e->getMessage());
    }
}

Prevention

When it happens

Trigger: _fetchAndInitializeUsersQuery (via fetchDirectoryData or getUserFiltersAsString) when directoryType === TYPE_AD AND enabledUsersOnly setting is true, and Parser::parse(DirectoryInterface::AD_ENABLED_USERS_FILTER) or Parser::assemble throws ParserException.

Common situations: LdapRecord/laminas-ldap dependency version with stricter filter grammar; AD_ENABLED_USERS_FILTER overridden/modified in a subclass; corrupted composer vendor directory where the parser can't handle multi-clause filters.

Related errors


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

Appendix: source

Thrown at plugins/PassboltEe/DirectorySync/src/Utility/LdapDirectory.php:403

    }

    /**
     * Fetch and initialize all users that are in the provided DN.
     *
     * @return \LdapRecord\Query\Builder query corresponding to the list of users.
     * @throws \InvalidArgumentException If an error occurred while parsing the enabledUsersOnly filter
     */
    private function _fetchAndInitializeUsersQuery(): Builder
    {
        $usersQuery = $this->_fetchAndInitializeQuery(self::ENTRY_TYPE_USER);
        $enabledUsersOnly = $this->directorySettings->getEnabledUsersOnly();
        $directoryType = $this->getDirectoryType();
        if ($directoryType === DirectoryInterface::TYPE_AD && $enabledUsersOnly) {
            try {
                $filter = Parser::parse(DirectoryInterface::AD_ENABLED_USERS_FILTER);
                $usersQuery->rawFilter(Parser::assemble($filter));
            } catch (ParserException $pe) {
                throw new InvalidArgumentException(
                    'An error has occurred parsing enabledUsersOnly filter: ' . $pe->getMessage(),
                    $pe->getCode(),
                    $pe
                );
            }
        }

        return $this->_customizeUsersQuery($usersQuery);
    }

    /**
     * Set specific objectClass for LDAP object and return query
     *
     * @param string $entryType Entry type (user, group)
     * @return \LdapRecord\Query\Model\Builder
     * @throws \RuntimeException If the entryType corresponding Ldap object class could not be found.
     * @throws \LdapRecord\Configuration\ConfigurationException When domain config key does not exist
     */

View on GitHub (pinned to 31c1bbc10f)