{"record":{"id":"66880ced257d2250","repo":"phacility/phabricator","slug":"trying-to-activate-lease-s-on-a-resource-s","errorCode":null,"errorMessage":"Trying to activate lease (\"%s\") on a resource (\"%s\") in the wrong status (\"%s\").","messagePattern":"Trying to activate lease \\(\"(.+?)\"\\) on a resource \\(\"(.+?)\"\\) in the wrong status \\(\"(.+?)\"\\)\\.","errorType":"exception","errorClass":"DrydockAcquiredBrokenResourceException","httpStatus":null,"severity":"error","filePath":"src/applications/drydock/worker/DrydockLeaseUpdateWorker.php","lineNumber":990,"sourceCode":"\n  /**\n   * @task activate\n   */\n  private function activateLease(DrydockLease $lease) {\n    $resource = $lease->getResource();\n    if (!$resource) {\n      throw new Exception(\n        pht('Trying to activate lease with no resource.'));\n    }\n\n    $resource_status = $resource->getStatus();\n\n    if ($resource_status == DrydockResourceStatus::STATUS_PENDING) {\n      throw new PhabricatorWorkerYieldException(15);\n    }\n\n    if ($resource_status != DrydockResourceStatus::STATUS_ACTIVE) {\n      throw new DrydockAcquiredBrokenResourceException(\n        pht(\n          'Trying to activate lease (\"%s\") on a resource (\"%s\") in '.\n          'the wrong status (\"%s\").',\n          $lease->getPHID(),\n          $resource->getPHID(),\n          $resource_status));\n    }\n\n    // NOTE: We can race resource destruction here. Between the time we\n    // performed the read above and now, the resource might have closed, so\n    // we may activate leases on dead resources. At least for now, this seems\n    // fine: a resource dying right before we activate a lease on it should not\n    // be distinguishable from a resource dying right after we activate a lease\n    // on it. We end up with an active lease on a dead resource either way, and\n    // can not prevent resources dying from lightning strikes.\n\n    $blueprint = $resource->getBlueprint();\n    $blueprint->activateLease($resource, $lease);","sourceCodeStart":972,"sourceCodeEnd":1008,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/drydock/worker/DrydockLeaseUpdateWorker.php#L972-L1008","documentation":"activateLease() requires the target resource to be STATUS_ACTIVE. If it is still STATUS_PENDING the worker yields 15 seconds and retries; any other status (broken, released, destroyed) throws DrydockAcquiredBrokenResourceException, which marks the acquired lease broken. This is the guard against activating leases on resources that died between acquisition and activation.","triggerScenarios":"The resource broke while the lease was waiting for it to finish activating (activation command failed); the resource was destroyed by reclamation after the lease was acquired; the resource was released by an admin while leases were pending.","commonSituations":"Working-copy resource whose git/hg clone fails during activation; host resource whose provisioning errored; lease activation racing resource destruction (the code comment explicitly acknowledges this race is tolerated upstream).","solutions":["If the status is pending, just wait: the worker yields and retries automatically.","If broken/destroyed, open the resource's event log to find why activation failed and fix that (command error, credentials, disk).","Re-run the lease acquisition against a healthy resource once the root cause is fixed."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"$status = $resource->getStatus();\nif ($status === DrydockResourceStatus::STATUS_PENDING) {\n  throw new PhabricatorWorkerYieldException(15); // still activating\n}\nif ($status !== DrydockResourceStatus::STATUS_ACTIVE) {\n  // broken/released/destroyed: fail before attempting activation\n  throw new Exception(pht('Resource not active: %s', $status));\n}","typeGuard":null,"tryCatchPattern":"try {\n  $this->activateLease($lease);\n} catch (DrydockAcquiredBrokenResourceException $ex) {\n  // resource died under the lease: log and re-acquire elsewhere\n  phlog($ex->getMessage());\n  $this->executeAllocator($lease);\n}","preventionTips":["Yield while the resource is pending instead of treating it as a hard failure.","Keep resource activation healthy (fix provisioning errors early) so leases never wait on broken resources."],"tags":["drydock","php","lease","resource-lifecycle","state-machine","race-condition"],"backgroundTag":"invalid-state-transition","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}