phacility/phabricator · error · Exception

Credential has invalid type "%s"!

Error message

Credential has invalid type "%s"!

What it means

Thrown by PassphraseCredentialPublicController when the public-key view (/K<id>/public) loads a credential whose stored type constant does not resolve to an installed PassphraseCredentialType implementation. The page needs the type object to check hasPublicKey() and to render the key, so an orphaned type constant fails before rendering. As with the other controllers, the message prints the null lookup result rather than the stored constant.

Source

Thrown at src/applications/passphrase/controller/PassphraseCredentialPublicController.php:25

    $viewer = $request->getViewer();
    $id = $request->getURIData('id');

    $credential = id(new PassphraseCredentialQuery())
      ->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()

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Read $credential->getCredentialType() and diff against constants from PassphraseCredentialType::getAllTypes().
  2. Restore the extension that owns the constant.
  3. Delete the orphaned credential and recreate it with a supported type.
Defensive patterns

Strategy: validation

Validate before calling

$all = PassphraseCredentialType::getAllTypes();
if (empty($all[$credential->getCredentialType()])) {
  // skip the /public link entirely
}

Type guard

function can_view_public_key($credential) {
  $type = PassphraseCredentialType::getTypeByConstant(
    $credential->getCredentialType());
  return $type !== null && $type->hasPublicKey();
}

Try / catch

try {
  $type = PassphraseCredentialType::getTypeByConstant(
    $credential->getCredentialType());
} catch (Exception $ex) {
  // suppress the public-key action for this credential
}

Prevention

When it happens

Trigger: Visiting /K<id>/public for a credential whose credentialType constant belongs to a removed or disabled extension.

Common situations: Links to the public-key page surviving in templates or bookmarks after the providing extension was disabled; cross-environment database restores.

Related errors


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