passbolt/passbolt_api · error · InvalidArgumentException

An error has occurred parsing groupCustomFilter

Error message

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

What it means

The groupCustomFilter string is parsed as an LDAP search filter; on syntax failure the ParserException is caught and rethrown as an InvalidArgumentException wrapping the parser message, indicating the group custom filter string is not a valid LDAP filter.

Solutions

  1. Fix the groupCustomFilter string so it is a valid RFC 4515 filter (balanced parens, escaped special characters)
  2. Use the parser message in the exception to pinpoint the syntax error
  3. Test the filter with ldapsearch or an LDAP filter validator before saving

Example fix

// before
$groupCustomFilter = '(&(objectClass=group)(cn=passbolt-*';
// after
$groupCustomFilter = '(&(objectClass=group)(cn=passbolt-*))';
Defensive patterns

Strategy: validation

Validate before calling

try {
    Parser::parse($groupCustomFilter);
} catch (ParserException $e) {
    // invalid filter, stop before group sync
}

Try / catch

try {
    $result = $sync->run();
} catch (InvalidArgumentException $e) {
    if (str_contains($e->getMessage(), 'parsing groupCustomFilter')) {
        // correct the group filter string
    }
}

Prevention

When it happens

Trigger: Calling _fetchAndInitializeGroupsQuery when the groupCustomFilter string fails Parser::parse() — malformed parentheses, operators, or escaping.

Common situations: Admin typo in the group filter field of directory sync settings, e.g. '(&(objectClass=group)(cn=passbolt-*' or filters using characters needing escaping like unescaped parentheses in CN values.

Related errors


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

Appendix: source

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

     *
     * @param \LdapRecord\Query\Builder $query query
     * @return \LdapRecord\Query\Builder
     * @throws \InvalidArgumentException If groupCustomFilter callback is used.
     * @throws \InvalidArgumentException If groupCustomFilter cannot be parsed.
     */
    private function _customizeGroupsQuery(Builder $query): Builder
    {
        $groupCustomFilter = $this->directorySettings->getGroupCustomFilters();
        if (is_callable($groupCustomFilter)) {
            throw new InvalidArgumentException(
                'Using callbacks for groupCustomFilter is not supported anymore. Please use LDAP search filter instead.'
            );
        } elseif (is_string($groupCustomFilter)) {
            try {
                $filter = Parser::parse($groupCustomFilter);
                $query->rawFilter(Parser::assemble($filter));
            } catch (ParserException $pe) {
                throw new InvalidArgumentException(
                    'An error has occurred parsing groupCustomFilter: ' . $pe->getMessage()
                );
            }
        }

        return $query;
    }

    /**
     * Return filters used to retrieve users as a string, in ldapsearch format.
     *
     * @return string
     * @throws \Exception
     */
    public function getUserFiltersAsString(): string
    {
        $query = $this->_fetchAndInitializeUsersQuery();

View on GitHub (pinned to 31c1bbc10f)