phacility/phabricator · error · PhutilArgumentUsageException
Multiple search engines match "%s": %s.
Error message
Multiple search engines match "%s": %s.
What it means
--class matching is a case-insensitive substring match, so a short argument can match several engine classes at once. When more than one class matches and none is an exact case-insensitive match, Phabricator refuses to guess and throws this usage exception listing every match. An exact class name always wins (the strtolower equality check breaks out immediately) and bypasses the ambiguity.
Source
Thrown at src/applications/transactions/bulk/management/PhabricatorBulkManagementExportWorkflow.php:202
if (stripos($class_name, $class) !== false) {
if (strtolower($class_name) == strtolower($class)) {
$matches = array($class_name);
break;
} else {
$matches[] = $class_name;
}
}
}
if (!$matches) {
throw new PhutilArgumentUsageException(
pht(
'No search engines match "%s". Available engines which support '.
'data export are: %s.',
$class,
$class_list));
} else if (count($matches) > 1) {
throw new PhutilArgumentUsageException(
pht(
'Multiple search engines match "%s": %s.',
$class,
implode(', ', $matches)));
} else {
$class = head($matches);
}
$engine = newv($class, array())
->setViewer($viewer);
} else {
$engine = null;
}
$queries = array();
foreach ($query_keys as $query_key) {
if ($engine) {
if ($engine->isBuiltinQuery($query_key)) {View on GitHub (pinned to 5720a38cfe)
Solutions
- Use the complete, exact engine class name (e.g. ManiphestTaskSearchEngine) — exact matches are unambiguous.
- Pick a longer substring unique to one engine, chosen from the match list printed in the error message.
- Pin scripts to full class names so they stay stable across upgrades.
Example fix
# before (fragment matches many engines) bin/bulk export --class Search --query all --output - # after bin/bulk export --class ManiphestTaskSearchEngine --query all --output -
Defensive patterns
Strategy: validation
Validate before calling
# require the argument to be a full class name in automation if [[ "$ENGINE" != *SearchEngine ]]; then echo 'use a full engine class name (e.g. ManiphestTaskSearchEngine)' >&2; exit 2 fi
Try / catch
Catch PhutilArgumentUsageException; when the message starts with 'Multiple search engines match', parse the listed matches and prompt the operator to choose one.
Prevention
- Always pass full class names in automation.
- Treat the error's match list as the menu when exploring interactively.
When it happens
Trigger: Passing a shared fragment such as --class Search (contained in nearly every *SearchEngine class) or --class Export when multiple export-capable engines contain it.
Common situations: Shortening long class names for convenience in manual commands; an upgrade registers new engines that now also match a substring that used to be unique.
Related errors
- No search engines match "%s". Available engines which suppor
- SearchEngine class ("%s") does not support data export.
- Use "--output <path>" to specify an output file, or "--outpu
- Flag "--overwrite" has no effect when outputting to stdout.
- Output path already exists. Use "--overwrite" to overwrite i
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/c0432f1e7a542456.
Report an issue: GitHub.