phacility/phabricator · warning · PhutilArgumentUsageException

Object " " specified by "--revision" must be a Differential…

Error message

Object "%s" specified by "--revision" must be a Differential revision.

What it means

rebuild-changesets resolves --revision first via PhabricatorObjectQuery->withNames(); if that lookup succeeds but the object is not a DifferentialRevision, the workflow throws this usage exception. The check exists because the generic name lookup happily resolves any monogram (tasks, mocks, repositories), but only revisions have rebuildable changesets.

Solutions

  1. Pass a Differential revision: --revision D<id> (or a bare numeric revision ID, which hits the fallback query)
  2. Fix the source that generated the wrong-prefixed monogram
  3. Validate the argument shape before running: it must match /^D?\d+$/

Example fix

# before
phabricator/ $ ./bin/differential rebuild-changesets --revision T456
Usage Exception: Object "T456" specified by "--revision" must be a Differential revision.

# after
phabricator/ $ ./bin/differential rebuild-changesets --revision D456
Defensive patterns

Strategy: validation

Validate before calling

// Validate the --revision value shape before running
if (!preg_match('/^D\\d+$|^\\d+$/', $revision_identifier)) {
  throw new Exception('Pass a Differential revision like D123 (or a bare numeric ID).');
}

Type guard

function isDifferentialMonogram($name) {
  return is_string($name) && preg_match('/^D\d+$/', $name);
}

Try / catch

try {
  $workflow->execute($args);
} catch (PhutilArgumentUsageException $ex) {
  // 'must be a Differential revision' -> the name resolved to another object;
  // correct the prefix to D (or use the bare numeric revision ID) and retry.
}

Prevention

When it happens

Trigger: Passing 'T456' (Maniphest task), 'M123' (mock), or another monogram in --revision; scripts templating a numeric ID with the wrong prefix; a name like 'D456' being shadowed by another object alias (rare) — note that if the generic lookup misses, the code falls back to DifferentialRevisionQuery->withIDs(), so a plain numeric ID is also accepted

Common situations: Automation that stores a single ticket number and derives both T and D references from it; users pasting a task monogram out of habit; hand-written runbooks mixing up object prefixes.

Related errors


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

Appendix: source

Thrown at src/applications/differential/management/PhabricatorDifferentialRebuildChangesetsWorkflow.php:36

        ));
  }

  public function execute(PhutilArgumentParser $args) {
    $viewer = $this->getViewer();

    $revision_identifier = $args->getArg('revision');
    if (!$revision_identifier) {
      throw new PhutilArgumentUsageException(
        pht('Specify a revision to rebuild changesets for with "--revision".'));
    }

    $revision = id(new PhabricatorObjectQuery())
      ->setViewer($viewer)
      ->withNames(array($revision_identifier))
      ->executeOne();
    if ($revision) {
      if (!($revision instanceof DifferentialRevision)) {
        throw new PhutilArgumentUsageException(
          pht(
            'Object "%s" specified by "--revision" must be a Differential '.
            'revision.',
            $revision_identifier));
      }
    } else {
      $revision = id(new DifferentialRevisionQuery())
        ->setViewer($viewer)
        ->withIDs(array($revision_identifier))
        ->executeOne();
    }

    if (!$revision) {
      throw new PhutilArgumentUsageException(
        pht(
          'No revision "%s" exists.',
          $revision_identifier));
    }

View on GitHub (pinned to 5720a38cfe)