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
- Pass a Differential revision monogram (D<id>) as the second argument
- Fix the upstream data source that produced the wrong object type so revisions are stored as D-monograms
- 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
- Never reuse a numeric ticket ID to synthesize multiple monogram types in scripts
- Validate object prefixes at the boundary where names enter your tooling
- Store object types alongside IDs in integration databases
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
- Object "%s" specified by "--revision" must be a Differential
- Specify a commit and a revision to attach it to.
- Commit "%s" does not exist.
- Revision "%s" does not exist.
- Specify a commit to extract the diff from.
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/ccd5d7c8ab63cc0e.
Report an issue: GitHub.