passbolt/passbolt_api · error · InvalidArgumentException
An error has occurred parsing userCustomFilter
Error message
An error has occurred parsing userCustomFilter: {pe->getMessage()} What it means
When userCustomFilter is a string, it is parsed as an LDAP search filter with LdapTools' Parser. If the string is not a syntactically valid LDAP filter, the ParserException is caught and rethrown as an InvalidArgumentException with the parser's message appended, explaining that the custom filter could not be parsed.
Solutions
- Read the appended ParserException message to locate the syntax problem
- Fix the userCustomFilter string to be a valid RFC 4515 LDAP filter with balanced parentheses and proper escaping
- Validate the filter against the LDAP directory (e.g. ldapsearch with the same filter) before saving it in settings
Example fix
// before $userCustomFilter = '(objectClass=user'; // after $userCustomFilter = '(objectClass=user)';
Defensive patterns
Strategy: validation
Validate before calling
try {
$parsed = \LdapTools\Query\Builder::parse($userCustomFilter); // or Parser::parse
} catch (ParserException $e) {
// abort before sync
} Try / catch
try {
$result = $sync->run();
} catch (InvalidArgumentException $e) {
if (str_starts_with($e->getMessage(), 'An error has occurred parsing userCustomFilter')) {
// fix settings, surface to admin
}
} Prevention
- Validate LDAP filters with ldapsearch before storing them
- Keep a small set of reviewed filter templates
- Escape parentheses and special chars in attribute values
When it happens
Trigger: Calling _fetchAndInitializeUsersQuery when directorySettings->getUserCustomFilters() returns a malformed string filter, causing Parser::parse() to throw.
Common situations: Hand-written LDAP filter with unbalanced parentheses, missing attribute/value, or wrong escaping (e.g. '(objectClass=user' or '(&(objectClass=user)(department=IT))' typos) entered in directory sync settings.
Related errors
- An error has occurred parsing groupCustomFilter
- The ldap integration is not configured or it is disabled
- Using callbacks for groupCustomFilter is not supported…
- Using callbacks for userCustomFilter is not supported…
- group(s) returned by your directory are invalid and will be…
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/3338c48149700343.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/DirectorySync/src/Utility/LdapDirectory.php:560
*
* @param \LdapRecord\Query\Builder $query query
* @return \LdapRecord\Query\Builder
* @throws \InvalidArgumentException If userCustomFilter callback is used.
* @throws \InvalidArgumentException If userCustomFilter cannot be parsed.
*/
private function _customizeUsersQuery(Builder $query): Builder
{
$userCustomFilter = $this->directorySettings->getUserCustomFilters();
if (is_callable($userCustomFilter)) {
throw new InvalidArgumentException(
'Using callbacks for userCustomFilter is not supported anymore. Please use LDAP search filter instead.'
);
} elseif (is_string($userCustomFilter)) {
try {
$filter = Parser::parse($userCustomFilter);
$query->rawFilter(Parser::assemble($filter));
} catch (ParserException $pe) {
throw new InvalidArgumentException(
'An error has occurred parsing userCustomFilter: ' . $pe->getMessage()
);
}
}
return $query;
}
/**
* Customize groups query as per configuration (if available).
*
* @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
{View on GitHub (pinned to 31c1bbc10f)