{"record":{"id":"4494bb2f3875655a","repo":"phacility/phabricator","slug":"blueprint-s-of-type-s-is-not-properly-impl","errorCode":null,"errorMessage":"Blueprint \"%s\" (of type \"%s\") is not properly implemented: %s must return an object of type %s or throw, but returned something else.","messagePattern":"Blueprint \"(.+?)\" \\(of type \"(.+?)\"\\) is not properly implemented: (.+?) must return an object of type (.+?) or throw, but returned something else\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/drydock/worker/DrydockLeaseUpdateWorker.php","lineNumber":830,"sourceCode":"\n\n  /**\n   * Check that the resource a blueprint allocated is roughly the sort of\n   * object we expect.\n   *\n   * @param DrydockBlueprint Blueprint which built the resource.\n   * @param wild Thing which the blueprint claims is a valid resource.\n   * @param DrydockLease Lease the resource was allocated for.\n   * @return void\n   * @task allocator\n   */\n  private function validateAllocatedResource(\n    DrydockBlueprint $blueprint,\n    $resource,\n    DrydockLease $lease) {\n\n    if (!($resource instanceof DrydockResource)) {\n      throw new Exception(\n        pht(\n          'Blueprint \"%s\" (of type \"%s\") is not properly implemented: %s must '.\n          'return an object of type %s or throw, but returned something else.',\n          $blueprint->getBlueprintName(),\n          $blueprint->getClassName(),\n          'allocateResource()',\n          'DrydockResource'));\n    }\n\n    if (!$resource->isAllocatedResource()) {\n      throw new Exception(\n        pht(\n          'Blueprint \"%s\" (of type \"%s\") is not properly implemented: %s '.\n          'must actually allocate the resource it returns.',\n          $blueprint->getBlueprintName(),\n          $blueprint->getClassName(),\n          'allocateResource()'));\n    }","sourceCodeStart":812,"sourceCodeEnd":848,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/drydock/worker/DrydockLeaseUpdateWorker.php#L812-L848","documentation":"After a blueprint's allocateResource() returns, DrydockLeaseUpdateWorker::validateAllocatedResource() checks that the returned value is actually a DrydockResource. Anything else (null, an array, an unrelated object) means the blueprint broke its contract: it must return the allocated resource or throw. This is a bug in blueprint code, not in the caller or configuration.","triggerScenarios":"A custom allocateResource() that forgets `return $resource;` on its success path (returns null); returning a template/DTO array or a PhabricatorObject instead of the DrydockResource; an early return on a path that skipped creating the resource.","commonSituations":"First draft of a custom blueprint; refactoring a blueprint and dropping the return statement; copying working-copy blueprint code and trimming too much.","solutions":["Make allocateResource() return the DrydockResource produced by newResourceTemplate() after calling $resource->allocateResource().","Add a return-type check in development: `if (!$resource instanceof DrydockResource) throw ...` before returning.","Compare against DrydockWorkingCopyBlueprintImplementation::allocateResource() for the canonical shape."],"exampleFix":"// before\npublic function allocateResource(DrydockBlueprint $blueprint, DrydockLease $lease) {\n  $this->provisionHost($blueprint);\n  // forgot to return the resource -> returns null\n}\n\n// after\npublic function allocateResource(DrydockBlueprint $blueprint, DrydockLease $lease) {\n  $this->provisionHost($blueprint);\n  return $this->newResourceTemplate($blueprint)->allocateResource();\n}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function isDrydockResource($value) {\n  return $value instanceof DrydockResource;\n}","tryCatchPattern":null,"preventionTips":["Add an instanceof self-check before returning from blueprint allocateResource() during development.","Copy the canonical allocateResource() shape from the working-copy blueprint."],"tags":["drydock","php","blueprint","contract","return-type"],"backgroundTag":"invalid-return-type","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}