phacility/phabricator · error · Exception
Credential has invalid type "%s"!
Error message
Credential has invalid type "%s"!
What it means
Thrown by PassphraseCredentialDestroyController when the destroy workflow (/K<id>/destroy) loads a credential whose stored type constant does not resolve to an installed PassphraseCredentialType implementation. The controller needs the type object to describe the secret being destroyed, so an orphaned type constant aborts before the confirmation dialog. As elsewhere in this controller family, the message prints the null $type rather than the stored constant.
Source
Thrown at src/applications/passphrase/controller/PassphraseCredentialDestroyController.php:26
$id = $request->getURIData('id');
$credential = id(new PassphraseCredentialQuery())
->setViewer($viewer)
->withIDs(array($id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$credential) {
return new Aphront404Response();
}
$type = PassphraseCredentialType::getTypeByConstant(
$credential->getCredentialType());
if (!$type) {
throw new Exception(pht('Credential has invalid type "%s"!', $type));
}
$view_uri = '/K'.$credential->getID();
if ($request->isFormPost()) {
$xactions = array();
$xactions[] = id(new PassphraseCredentialTransaction())
->setTransactionType(
PassphraseCredentialDestroyTransaction::TRANSACTIONTYPE)
->setNewValue(1);
$editor = id(new PassphraseCredentialTransactionEditor())
->setActor($viewer)
->setContinueOnMissingFields(true)
->setContentSourceFromRequest($request)
->applyTransactions($credential, $xactions);
View on GitHub (pinned to 5720a38cfe)
Solutions
- Read the credential's stored constant via $credential->getCredentialType() and list registered types with PassphraseCredentialType::getAllTypes().
- Restore the extension providing that constant, then retry the destroy action.
- If restoring is impossible, remove the orphaned row directly (or via a script) since the credential can no longer be used anyway.
Defensive patterns
Strategy: validation
Validate before calling
$type_const = $credential->getCredentialType();
$all = PassphraseCredentialType::getAllTypes();
if (empty($all[$type_const])) {
// cannot render destroy dialog: restore the extension or remove the row
} Type guard
function credential_type_is_installed($credential) {
$all = PassphraseCredentialType::getAllTypes();
return isset($all[$credential->getCredentialType()]);
} Try / catch
try {
$type = PassphraseCredentialType::getTypeByConstant(
$credential->getCredentialType());
} catch (Exception $ex) {
// surface the stored constant and block the destroy action
} Prevention
- Before uninstalling a credential type extension, destroy or migrate its credentials first.
- Rehearse extension removals on a staging copy of the database.
- Monitor for credentials whose type constant is absent from getAllTypes().
When it happens
Trigger: Requesting /K<id>/destroy for a credential whose credentialType came from a disabled or removed extension (custom type class uninstalled after credentials of that type were created).
Common situations: Cleaning up after disabling a site extension that registered credential types; restoring a database to an install with a different extension set; renaming a type class without migrating its CREDENTIAL_TYPE constant.
Related errors
- Credential has invalid type "%s"!
- Credential has invalid type "%s"!
- Credential has invalid type "%s"!
- Credential has invalid type "%s"!
- Credential "%s" is of unknown type "%s"!
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/5b2b4e4264c0a2ef.
Report an issue: GitHub.