phacility/phabricator · error · PhutilArgumentUsageException

Specified queries use different engines: query "%s" uses eng

Error message

Specified queries use different engines: query "%s" uses engine "%s", not "%s". All queries must run on the same engine.

What it means

A single export run uses one search engine. When multiple --query keys are given, the code takes the first query's engine class (or the --class engine) and throws this usage exception if any later query's getEngineClassName() differs. The union-query path (newUnionQuery, used when count($queries) > 1) also requires all queries to run on one engine, since it merges result IDs into one synthetic query.

Source

Thrown at src/applications/transactions/bulk/management/PhabricatorBulkManagementExportWorkflow.php:265

      $queries[$query_key] = $saved_query;
    }

    // If we don't have an engine from "--class", fill it in by looking at the
    // class of the first query.
    if (!$engine) {
      foreach ($queries as $query) {
        $engine = newv($query->getEngineClassName(), array())
          ->setViewer($viewer);
        break;
      }
    }

    $engine_class = get_class($engine);

    foreach ($queries as $query) {
      $query_class = $query->getEngineClassName();
      if ($query_class !== $engine_class) {
        throw new PhutilArgumentUsageException(
          pht(
            'Specified queries use different engines: query "%s" uses '.
            'engine "%s", not "%s". All queries must run on the same '.
            'engine.',
            $query->getQueryKey(),
            $query_class,
            $engine_class));
      }
    }

    if (!$engine->canExport()) {
      throw new PhutilArgumentUsageException(
        pht(
          'SearchEngine class ("%s") does not support data export.',
          $engine_class));
    }

    return array($engine, $queries);

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Split the invocation per application: one command per engine with only that engine's query keys, then merge the files downstream.
  2. Pin --class explicitly and audit that every --query key belongs to that engine before running.
  3. To union results inside one application, pass several saved queries from that same application.

Example fix

# before (keys belong to different engines)
bin/bulk export --query ${TASK_KEY} --query ${REVISION_KEY} --output -
# after (one engine per invocation)
bin/bulk export --query ${TASK_KEY} --output tasks.csv
bin/bulk export --class DifferentialRevisionSearchEngine --query ${REVISION_KEY} --output revs.csv
Defensive patterns

Strategy: validation

Validate before calling

# group saved-query keys per engine before invoking
for engine in "${!KEYS_BY_ENGINE[@]}"; do
  bin/bulk export --class "$engine" "${KEYS_BY_ENGINE[$engine]}" --output "out-$engine.csv"
done

Try / catch

Catch PhutilArgumentUsageException, detect 'use different engines', and split the invocation automatically per engine class before retrying once.

Prevention

When it happens

Trigger: Passing --query A --query B where A is a Maniphest saved query and B a Differential saved query; combining keys collected from different applications' UI searches into one invocation.

Common situations: Trying to build one combined CSV of tasks and revisions; consolidating several recurring exports into a single command during cleanup.

Related errors


AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21). Data as JSON: /api/errors/c66735d8e2531cd0. Report an issue: GitHub.