phacility/phabricator · error · ConduitException

ERR-BAD-PHID

ERR-BAD-PHID

Error message

ERR-BAD-PHID

What it means

Conduit method phid.query (PHIDInfoConduitAPIMethod) resolves the supplied phid through PhabricatorHandleQuery with the API user as viewer. If the resulting handle is not complete - the PHID is malformed, refers to a deleted object, or to an object the acting user cannot see - the method raises ConduitException with error code ERR-BAD-PHID. It signals an unresolvable identifier rather than a transport failure.

Source

Thrown at src/applications/phid/conduit/PHIDInfoConduitAPIMethod.php:46

    return 'nonempty dict<string, wild>';
  }

  protected function defineErrorTypes() {
    return array(
      'ERR-BAD-PHID' => pht('No such object exists.'),
    );
  }

  protected function execute(ConduitAPIRequest $request) {
    $phid = $request->getValue('phid');

    $handle = id(new PhabricatorHandleQuery())
      ->setViewer($request->getUser())
      ->withPHIDs(array($phid))
      ->executeOne();

    if (!$handle->isComplete()) {
      throw new ConduitException('ERR-BAD-PHID');
    }

    return $this->buildHandleInformationDictionary($handle);
  }

}

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Validate the PHID shape first (matches /^PHID-[A-Z]{2,4}-/ before calling)
  2. Resolve monograms with phid.lookup ('T123', 'D45') to obtain real PHIDs
  3. If deleted or policy-hidden objects are expected, catch the ConduitException and skip entries with code ERR-BAD-PHID

Example fix

// before
$info = $conduit->executeMethod('phid.query', array('phid' => $phid)); // raw call
// after
if (!preg_match('/^PHID-[A-Z]{2,4}-/', $phid)) {
  continue; // not a PHID; resolve via phid.lookup instead
}
try {
  $info = $conduit->executeMethod('phid.query', array('phid' => $phid));
} catch (ConduitClientException $ex) {
  if ($ex->getErrorCode() === 'ERR-BAD-PHID') { continue; }
  throw $ex;
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!preg_match('/^PHID-[A-Z]{2,4}-[a-z0-9]+$/', $phid)) {
  // not a well-formed PHID; resolve monograms via phid.lookup first
  return null;
}

Type guard

function isLikelyPhid($value) {
  return is_string($value) && preg_match('/^PHID-[A-Z]{2,4}-/', $value) === 1;
}

Try / catch

try {
  $info = $conduit->executeMethod('phid.query', array('phid' => $phid));
} catch (ConduitClientException $ex) {
  if ($ex->getErrorCode() === 'ERR-BAD-PHID') {
    // unknown, deleted, or policy-hidden object: skip it
    continue;
  }
  throw $ex;
}

Prevention

When it happens

Trigger: Calling phid.query with a typo'd or truncated PHID; passing a monogram like T123 where a PHID (PHID-TASK-...) is required; referencing a deleted object's PHID from stale exports; the API token's owner lacking policy visibility on the object.

Common situations: Integrations piping old PHIDs from previous exports; string concatenation bugs mangling identifiers; permission mismatch between the Conduit token owner and the object's view policy.

Related errors


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