phacility/phabricator · error · Exception
Credential has no public key!
Error message
Credential has no public key!
What it means
Thrown by PassphraseCredentialPublicController when the credential's type implementation returns false from hasPublicKey(). Only key-like types (SSH keys, certificates) can expose a public component; password, token, and other secret types have no public view at all, so the /K<id>/public page rejects them before calling getPublicKey().
Source
Thrown at src/applications/passphrase/controller/PassphraseCredentialPublicController.php:29
->setViewer($viewer)
->withIDs(array($id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
))
->executeOne();
if (!$credential) {
return new Aphront404Response();
}
$type = PassphraseCredentialType::getTypeByConstant(
$credential->getCredentialType());
if (!$type) {
throw new Exception(pht('Credential has invalid type "%s"!', $type));
}
if (!$type->hasPublicKey()) {
throw new Exception(pht('Credential has no public key!'));
}
$view_uri = '/'.$credential->getMonogram();
$public_key = $type->getPublicKey($viewer, $credential);
$body = id(new PHUIFormLayoutView())
->appendChild(
id(new AphrontFormTextAreaControl())
->setLabel(pht('Public Key'))
->setReadOnly(true)
->setValue($public_key));
return $this->newDialog()
->setWidth(AphrontDialogView::WIDTH_FORM)
->setTitle(pht('Public Key (%s)', $credential->getMonogram()))
->appendChild($body)
->addCancelButton($view_uri, pht('Done'));View on GitHub (pinned to 5720a38cfe)
Solutions
- Only render/expose the public-key link when $type->hasPublicKey() is true.
- For non-key credentials, use the appropriate workflow (secret reveal under high security, or the type's own views).
- Hide the action in menus and object lists rather than letting the page throw.
Example fix
// before
$items[] = id(new PHUIListItemView())
->setHref('/K'.$credential->getID().'/public')
->setName(pht('Public Key'));
// after
$type = $credential->getImplementation();
if ($type && $type->hasPublicKey()) {
$items[] = id(new PHUIListItemView())
->setHref('/K'.$credential->getID().'/public')
->setName(pht('Public Key'));
} Defensive patterns
Strategy: validation
Validate before calling
$type = PassphraseCredentialType::getTypeByConstant(
$credential->getCredentialType());
if (!$type || !$type->hasPublicKey()) {
// do not link or route to /K<id>/public
} Type guard
function credential_has_public_key($credential) {
$type = $credential->getImplementation();
return $type !== null && $type->hasPublicKey();
} Try / catch
try {
$public_key = $type->getPublicKey($viewer, $credential);
} catch (Exception $ex) {
// wrong credential kind: prompt for a key-type credential
} Prevention
- Render the 'Public Key' action only when hasPublicKey() is true.
- Filter credential pickers by provides type so users never select key-incompatible credentials for key workflows.
- Teach users that password/token credentials intentionally have no public view.
When it happens
Trigger: Navigating to /K<id>/public for a password, API-token, or other non-key credential; templates or menus that unconditionally link the 'Public Key' action for every credential.
Common situations: UI code assuming every credential has a public view; scripts scraping the public-key page for all credentials in an install; users hand-entering the URL.
Related errors
- Credential has noncreateable type "%s"!
- Credential has invalid type "%s"!
- Credential has invalid type "%s"!
- This public key is already associated with another user or d
- No public key was provided.
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/b6db52558b474f96.
Report an issue: GitHub.