phacility/phabricator · warning · PhutilArgumentUsageException

Object "%s" must be a Differential revision.

Error message

Object "%s" must be a Differential revision.

What it means

attach-commit resolves the second argument generically with PhabricatorObjectQuery (any object name can match) and then asserts the result is a DifferentialRevision. If the name resolves to a different object type — a task, file, mock, or repository — the workflow throws rather than attaching a commit to an incompatible object.

Source

Thrown at src/applications/differential/management/PhabricatorDifferentialAttachCommitWorkflow.php:53

      ->withIdentifiers(array($commit_name))
      ->executeOne();
    if (!$commit) {
      throw new PhutilArgumentUsageException(
        pht('Commit "%s" does not exist.', $commit_name));
    }

    $revision = id(new PhabricatorObjectQuery())
      ->setViewer($viewer)
      ->withNames(array($revision_name))
      ->executeOne();

    if (!$revision) {
      throw new PhutilArgumentUsageException(
        pht('Revision "%s" does not exist.', $revision_name));
    }

    if (!($revision instanceof DifferentialRevision)) {
      throw new PhutilArgumentUsageException(
        pht('Object "%s" must be a Differential revision.', $revision_name));
    }

    // Reload the revision to get the active diff.
    $revision = id(new DifferentialRevisionQuery())
      ->setViewer($viewer)
      ->withIDs(array($revision->getID()))
      ->needActiveDiffs(true)
      ->executeOne();

    $differential_phid = id(new PhabricatorDifferentialApplication())
      ->getPHID();

    $extraction_engine = id(new DifferentialDiffExtractionEngine())
      ->setViewer($viewer)
      ->setAuthorPHID($differential_phid);

    $content_source = $this->newContentSource();

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Pass a Differential revision monogram (D<id>) as the second argument
  2. Fix the upstream data source that produced the wrong object type so revisions are stored as D-monograms
  3. If you scripted this, validate the prefix with a regex like /^D\d+$/ before invoking

Example fix

# before
phabricator/ $ ./bin/differential attach-commit rP703dcf5 T456
Usage Exception: Object "T456" must be a Differential revision.

# after
phabricator/ $ ./bin/differential attach-commit rP703dcf5 D456
Defensive patterns

Strategy: validation

Validate before calling

// Validate the second argument is a revision monogram before running:
if (!preg_match('/^D\d+$/', $revision_name)) {
  throw new Exception('Expected a Differential revision monogram like D123.');
}

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 type;
  // correct the monogram prefix (T/M/F are not D) and retry.
}

Prevention

When it happens

Trigger: Passing 'T456' (Maniphest task) or another monogram where a revision was intended; a name that happens to match a non-revision object (e.g., an M/phrabricator mock); scripts that template the same numeric suffix across object types and drop the D prefix; passing a project or user name that collides with an object name.

Common situations: Automated scripts that build object names from a shared ticket number; users pasting the wrong monogram (T vs D); integrations that store mixed object identifiers in one field.

Related errors


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