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
- Validate the PHID shape first (matches /^PHID-[A-Z]{2,4}-/ before calling)
- Resolve monograms with phid.lookup ('T123', 'D45') to obtain real PHIDs
- 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
- Validate PHID shape before calling phid.query
- Resolve monograms (T123/D45) with phid.lookup to get real PHIDs
- Treat ERR-BAD-PHID as an expected, skippable condition when processing stale exports
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
- Source PHID "%s" does not identify a valid object, or you do
- API Method "%s" defines a disallowed parameter, "%s". This p
- API Method "%s" does not define these parameters: %s.
- Conduit API method "%s" does not exist.
- When creating a new Drydock blueprint via the Conduit API, y
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/f60e44fc785f1490.
Report an issue: GitHub.