phacility/phabricator · error · Exception

When creating a new Drydock blueprint via the Conduit API, y

Error message

When creating a new Drydock blueprint via the Conduit API, you must provide a "type" transaction to select a type.

What it means

Thrown by DrydockBlueprintEditEngine::newEditableObjectFromConduit() when a Conduit 'drydock.blueprint.edit' call creates a new blueprint without a transaction of type 'type'. Blueprint type cannot be inferred or defaulted because the concrete DrydockBlueprintImplementation must be selected before the object can even be constructed, so the edit engine requires exactly one 'type' transaction in the raw transaction list for creates.

Source

Thrown at src/applications/drydock/editor/DrydockBlueprintEditEngine.php:65

        ->setClassName(get_class($impl))
        ->attachImplementation(clone $impl);
    }

    return $blueprint;
  }

  protected function newEditableObjectFromConduit(array $raw_xactions) {
    $type = null;
    foreach ($raw_xactions as $raw_xaction) {
      if ($raw_xaction['type'] !== 'type') {
        continue;
      }

      $type = $raw_xaction['value'];
    }

    if ($type === null) {
      throw new Exception(
        pht(
          'When creating a new Drydock blueprint via the Conduit API, you '.
          'must provide a "type" transaction to select a type.'));
    }

    $map = DrydockBlueprintImplementation::getAllBlueprintImplementations();
    if (!isset($map[$type])) {
      throw new Exception(
        pht(
          'Blueprint type "%s" is unrecognized. Valid types are: %s.',
          $type,
          implode(', ', array_keys($map))));
    }

    $impl = clone $map[$type];
    $this->setBlueprintImplementation($impl);

    return $this->newEditableObject();

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Add a type transaction as the first entry: {'type': 'type', 'value': 'host'} (or another registered blueprint type), then re-issue the Conduit call.
  2. Check the transaction name spelling — it must be exactly the literal string 'type'.
  3. For subsequent edits of an existing blueprint, pass its object identifier (id/phid) so the call no longer needs the type transaction.

Example fix

// before
$result = $client->callMethodSynchronous(
  'drydock.blueprint.edit',
  array(
    'transactions' => array(
      array('type' => 'name', 'value' => 'Host Blueprint'),
    ),
  ));

// after
$result = $client->callMethodSynchronous(
  'drydock.blueprint.edit',
  array(
    'transactions' => array(
      array('type' => 'type', 'value' => 'host'),
      array('type' => 'name', 'value' => 'Host Blueprint'),
    ),
  ));
Defensive patterns

Strategy: validation

Validate before calling

$has_type = false;
foreach ($transactions as $xaction) {
  if ($xaction['type'] === 'type' && idx($xaction, 'value') !== null) {
    $has_type = true;
  }
}
if (!$has_type && $object_identifier === null) {
  throw new InvalidArgumentException(
    'Blueprint creation via Conduit requires a type transaction.');
}

Prevention

When it happens

Trigger: Calling drydock.blueprint.edit with a transactions array that contains only field edits (e.g. [{'type': 'name', 'value': '...'}]) and no {'type': 'type', 'value': ...} entry, without passing an object identifier (i.e. a create, not an edit). The loop over $raw_xactions leaves $type === null and the exception fires.

Common situations: Porting a script from another application's *.edit Conduit method where type is optional; building blueprints programmatically in setup automation and forgetting the type; sending the type under a wrong transaction name (e.g. 'blueprint-type' or 'class').

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


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