phacility/phabricator · error · Exception

Blueprint "%s" (of type "%s") is not properly implemented: i

Error message

Blueprint "%s" (of type "%s") is not properly implemented: it built a resource of type "%s" to satisfy a lease requesting a resource of type "%s".

What it means

The third validation in validateAllocatedResource() compares the built resource's getType() with the lease's getResourceType(); they must be identical strings. The blueprint claimed to serve the lease's type but constructed a resource of a different type, so the lease could never use it. This is a blueprint implementation bug, typically a hardcoded or mismatched type string.

Source

Thrown at src/applications/drydock/worker/DrydockLeaseUpdateWorker.php:854

          'allocateResource()',
          'DrydockResource'));
    }

    if (!$resource->isAllocatedResource()) {
      throw new Exception(
        pht(
          'Blueprint "%s" (of type "%s") is not properly implemented: %s '.
          'must actually allocate the resource it returns.',
          $blueprint->getBlueprintName(),
          $blueprint->getClassName(),
          'allocateResource()'));
    }

    $resource_type = $resource->getType();
    $lease_type = $lease->getResourceType();

    if ($resource_type !== $lease_type) {
      throw new Exception(
        pht(
          'Blueprint "%s" (of type "%s") is not properly implemented: it '.
          'built a resource of type "%s" to satisfy a lease requesting a '.
          'resource of type "%s".',
          $blueprint->getBlueprintName(),
          $blueprint->getClassName(),
          $resource_type,
          $lease_type));
    }
  }

  private function reclaimResources(
    DrydockBlueprint $blueprint,
    DrydockLease $lease) {
    $viewer = $this->getViewer();

    $resources = id(new DrydockResourceQuery())
      ->setViewer($viewer)

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Create the template with exactly the lease's type: $this->newResourceTemplate() with getType() matching $lease->getResourceType().
  2. Use $this->getType() (the implementation's declared type) as the single source of truth instead of string literals.
  3. Check for casing/whitespace differences between the blueprint type and the lease's requested resource type.

Example fix

// before
$resource = $this->newResourceTemplate($blueprint)
  ->setAttribute('type', 'host'); // blueprint serves 'working-copy'

// after
$resource = $this->newResourceTemplate($blueprint); // type comes from getType(), matches lease
Defensive patterns

Strategy: validation

Validate before calling

if ($resource->getType() !== $lease->getResourceType()) {
  throw new Exception(
    pht('Blueprint built "%s" for a lease of type "%s".',
      $resource->getType(), $lease->getResourceType()));
}

Prevention

When it happens

Trigger: A custom allocateResource() that calls newResourceTemplate() with a fixed type like 'host' while the lease requested 'working-copy'; a blueprint implementation whose getType() was renamed but the template creation still uses the old literal; differing casing or spelling between the two strings.

Common situations: One blueprint implementation reused to build several resource types; type renames across Phabricator versions; copy-paste between host and working-copy blueprints.

Related errors


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