{"record":{"id":"86af00d02c96b104","repo":"phacility/phabricator","slug":"trying-to-activate-a-resource-which-has-not-yet-be","errorCode":null,"errorMessage":"Trying to activate a resource which has not yet been persisted.","messagePattern":"Trying to activate a resource which has not yet been persisted\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/drydock/storage/DrydockResource.php","lineNumber":190,"sourceCode":"\n    $this->saveTransaction();\n\n    $this->isAllocated = true;\n\n    if ($new_status == DrydockResourceStatus::STATUS_ACTIVE) {\n      $this->didActivate();\n    }\n\n    return $this;\n  }\n\n  public function isAllocatedResource() {\n    return $this->isAllocated;\n  }\n\n  public function activateResource() {\n    if (!$this->getID()) {\n      throw new Exception(\n        pht(\n          'Trying to activate a resource which has not yet been persisted.'));\n    }\n\n    $expect_status = DrydockResourceStatus::STATUS_PENDING;\n    $actual_status = $this->getStatus();\n    if ($actual_status != $expect_status) {\n      throw new Exception(\n        pht(\n          'Trying to activate a resource from the wrong status. Status must '.\n          'be \"%s\", actually \"%s\".',\n          $expect_status,\n          $actual_status));\n    }\n\n    $this->openTransaction();\n\n    try {","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/drydock/storage/DrydockResource.php#L172-L208","documentation":"DrydockResource::activateResource() refuses to activate a resource that has no database ID, i.e. one that was never saved. The activation flow (slot locks, status transition, didActivate) only works on a persisted row. This almost always means a blueprint created a resource template but never called allocateResource(), which is the step that persists it.","triggerScenarios":"Calling activateResource() on a resource returned by DrydockBlueprintImplementation::newResourceTemplate() without first calling $resource->allocateResource(); custom code that constructs a DrydockResource in memory (setStatus + setPHID) and tries to activate it before save().","commonSituations":"Writing a custom Drydock blueprint and skipping the allocateResource() call inside allocateResource(); copying an example that pre-dates the allocate/activate split; activating a resource twice across code paths where the first call never persisted it.","solutions":["Call $resource->allocateResource() (which acquires slot locks and saves the row with status pending or active) before calling activateResource().","Create resources through $this->newResourceTemplate($blueprint) inside blueprint allocateResource() so the PHID/defaults are pregenerated.","If activating an existing resource, reload it with DrydockResourceQuery so it has an ID instead of using a fresh in-memory object."],"exampleFix":"// before\n$resource = $this->newResourceTemplate($blueprint);\n$resource->activateResource(); // throws: not persisted\n\n// after\n$resource = $this->newResourceTemplate($blueprint);\n$resource->allocateResource();   // persists (status pending)\nreturn $resource;                // worker later calls activateResource()","handlingStrategy":"validation","validationCode":"if (!$resource->getID()) {\n  throw new Exception(\n    pht('Resource is not persisted; call allocateResource() first.'));\n}\n$resource->activateResource();","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always create Drydock resources via newResourceTemplate() and persist them with allocateResource() before any activation step.","Treat an object with no ID as a template, never as a live resource."],"tags":["drydock","php","resource-lifecycle","unsaved-entity","state-machine"],"backgroundTag":"object-not-persisted","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}