phacility/phabricator · error · Exception

Credential has noncreateable type "%s"!

Error message

Credential has noncreateable type "%s"!

What it means

Thrown by PassphraseCredentialEditController when a user tries to create a NEW credential of a type that exists but returns false from isCreateable(). Some credential types are internal: they are minted by other machinery (automation tokens, generated keys) and must not be hand-created through the passphrase create form. Editing an existing credential of such a type is allowed; only manual creation is blocked.

Source

Thrown at src/applications/passphrase/controller/PassphraseCredentialEditController.php:32

          array(
            PhabricatorPolicyCapability::CAN_VIEW,
            PhabricatorPolicyCapability::CAN_EDIT,
          ))
        ->executeOne();
      if (!$credential) {
        return new Aphront404Response();
      }

      $type = $this->getCredentialType($credential->getCredentialType());
      $type_const = $type->getCredentialType();

      $is_new = false;
    } else {
      $type_const = $request->getStr('type');
      $type = $this->getCredentialType($type_const);

      if (!$type->isCreateable()) {
        throw new Exception(
          pht(
            'Credential has noncreateable type "%s"!',
            $type_const));
      }

      $credential = PassphraseCredential::initializeNewCredential($viewer)
        ->setCredentialType($type->getCredentialType())
        ->setProvidesType($type->getProvidesType())
        ->attachImplementation($type);

      $is_new = true;

      // Prefill username if provided.
      $credential->setUsername((string)$request->getStr('username'));

      if (!$request->getStr('isInitialized')) {
        $type->didInitializeNewCredential($viewer, $credential);
      }

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Pick a user-createable type in the create form (drop the type parameter so the form only lists createable types).
  2. If the type should be manually createable, override isCreateable() to return true in its implementation.
  3. Route users to the workflow that mints the internal credential instead of the generic create form.

Example fix

// before
$type_const = $request->getStr('type');
$type = $this->getCredentialType($type_const);
if (!$type->isCreateable()) {
  throw new Exception(pht('Credential has noncreateable type "%s"!', $type_const));
}

// after: only offer types that allow manual creation
$all_types = PassphraseCredentialType::getAllTypes();
$type = idx($all_types, $request->getStr('type'));
$createable = mpick(
  mfilter($all_types, 'isCreateable'),
  'getCredentialType');
if (!$type || !isset($createable[$type->getCredentialType()])) {
  $type = idx($all_types, key($createable));
}
Defensive patterns

Strategy: validation

Validate before calling

$createable = mpick(
  mfilter(PassphraseCredentialType::getAllTypes(), 'isCreateable'),
  'getCredentialType');
if (!isset($createable[$requested_const])) {
  $requested_const = null; // fall back to the default createable type
}

Type guard

function is_createable_credential_type($type_const) {
  $createable = mpick(
    mfilter(PassphraseCredentialType::getAllTypes(), 'isCreateable'),
    'getCredentialType');
  return isset($createable[$type_const]);
}

Try / catch

try {
  // create credential of $type_const
} catch (Exception $ex) {
  if (preg_match('/noncreateable/', $ex->getMessage())) {
    // retry with a type selected from isCreateable()-filtered list
  }
}

Prevention

When it happens

Trigger: POSTing to /passphrase/edit/ with a 'type' request parameter naming a non-createable implementation; deep-linking the create form with ?type=<internal-constant>.

Common situations: A custom PassphraseCredentialType intended only for machine use where the developer forgot users can still reach the create form via the type parameter; links or templates carrying an internal type constant into the create workflow.

Related errors


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