{"record":{"id":"c0432f1e7a542456","repo":"phacility/phabricator","slug":"multiple-search-engines-match-s-s","errorCode":null,"errorMessage":"Multiple search engines match \"%s\": %s.","messagePattern":"Multiple search engines match \"(.+?)\": (.+?)\\.","errorType":"console","errorClass":"PhutilArgumentUsageException","httpStatus":null,"severity":"error","filePath":"src/applications/transactions/bulk/management/PhabricatorBulkManagementExportWorkflow.php","lineNumber":202,"sourceCode":"        if (stripos($class_name, $class) !== false) {\n          if (strtolower($class_name) == strtolower($class)) {\n            $matches = array($class_name);\n            break;\n          } else {\n            $matches[] = $class_name;\n          }\n        }\n      }\n\n      if (!$matches) {\n        throw new PhutilArgumentUsageException(\n          pht(\n            'No search engines match \"%s\". Available engines which support '.\n            'data export are: %s.',\n            $class,\n            $class_list));\n      } else if (count($matches) > 1) {\n        throw new PhutilArgumentUsageException(\n          pht(\n            'Multiple search engines match \"%s\": %s.',\n            $class,\n            implode(', ', $matches)));\n      } else {\n        $class = head($matches);\n      }\n\n      $engine = newv($class, array())\n        ->setViewer($viewer);\n    } else {\n      $engine = null;\n    }\n\n    $queries = array();\n    foreach ($query_keys as $query_key) {\n      if ($engine) {\n        if ($engine->isBuiltinQuery($query_key)) {","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/transactions/bulk/management/PhabricatorBulkManagementExportWorkflow.php#L184-L220","documentation":"--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.","triggerScenarios":"Passing a shared fragment such as --class Search (contained in nearly every *SearchEngine class) or --class Export when multiple export-capable engines contain it.","commonSituations":"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.","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."],"exampleFix":"# before (fragment matches many engines)\nbin/bulk export --class Search --query all --output -\n# after\nbin/bulk export --class ManiphestTaskSearchEngine --query all --output -","handlingStrategy":"validation","validationCode":"# require the argument to be a full class name in automation\nif [[ \"$ENGINE\" != *SearchEngine ]]; then\n  echo 'use a full engine class name (e.g. ManiphestTaskSearchEngine)' >&2; exit 2\nfi","typeGuard":null,"tryCatchPattern":"Catch PhutilArgumentUsageException; when the message starts with 'Multiple search engines match', parse the listed matches and prompt the operator to choose one.","preventionTips":["Always pass full class names in automation.","Treat the error's match list as the menu when exploring interactively."],"tags":["phabricator","cli","export","search-engine"],"backgroundTag":"ambiguous-identifier","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}