{"record":{"id":"3e328e1426233606","repo":"phacility/phabricator","slug":"lease-has-already-been-destroyed","errorCode":null,"errorMessage":"Lease has already been destroyed!","messagePattern":"Lease has already been destroyed!","errorType":"console","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/drydock/management/DrydockManagementLeaseWorkflow.php","lineNumber":250,"sourceCode":"        }\n\n        echo tsprintf(\n          \"(Lease #%d) <%s> %B\\n\",\n          $lease->getID(),\n          $type,\n          $data);\n      }\n\n      $status = $lease->getStatus();\n\n      switch ($status) {\n        case DrydockLeaseStatus::STATUS_ACTIVE:\n          $is_active = true;\n          break;\n        case DrydockLeaseStatus::STATUS_RELEASED:\n          throw new Exception(pht('Lease has already been released!'));\n        case DrydockLeaseStatus::STATUS_DESTROYED:\n          throw new Exception(pht('Lease has already been destroyed!'));\n        case DrydockLeaseStatus::STATUS_BROKEN:\n          throw new Exception(pht('Lease has been broken!'));\n        case DrydockLeaseStatus::STATUS_PENDING:\n        case DrydockLeaseStatus::STATUS_ACQUIRED:\n          break;\n        default:\n          throw new Exception(\n            pht(\n              'Lease has unknown status \"%s\".',\n              $status));\n      }\n\n      if ($is_active) {\n        break;\n      } else {\n        sleep(1);\n      }\n    }","sourceCodeStart":232,"sourceCodeEnd":268,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/drydock/management/DrydockManagementLeaseWorkflow.php#L232-L268","documentation":"Same wait loop in `bin/drydock lease`, but the lease status is STATUS_DESTROYED: the underlying resource (or the lease itself) was destroyed before activation completed. Destruction can be triggered by an operator, by the resource being broken and cleaned up, or by daemons reclaiming resources, and it is terminal — the CLI stops waiting immediately.","triggerScenarios":"Polling a lease whose resource was destroyed concurrently: an operator destroys the host resource from the Drydock console, or a cleaner daemon destroys pending resources while the lease is still being allocated.","commonSituations":"Manual cleanup of a stuck allocation while the lease command is still waiting; aggressive reclamation settings destroying slow-pending resources; test runs on blueprints that get torn down mid-flight.","solutions":["Re-run the lease command to get a new lease on a live resource.","Check the Drydock resource console for why the resource was destroyed (operator action vs. daemon) and address the root cause.","Avoid destroying resources while leases against them are still activating; check active leases first."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if (!$lease->isActive() &&\n    $lease->getStatus() === DrydockLeaseStatus::STATUS_DESTROYED) {\n  throw new RuntimeException(\n    \"Lease {$lease->getID()} was destroyed; re-acquire.\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  $lease->waitUntilActive();\n} catch (Exception $ex) {\n  if (preg_match('/already been destroyed/', $ex->getMessage())) {\n    // terminal: verify the backing resource still exists, then re-acquire\n    $lease = acquireNewLease($attributes);\n  } else {\n    throw $ex;\n  }\n}","preventionTips":["Do not destroy Drydock resources from automation or the console while leases against them are still activating.","Treat destroy-during-wait as an operational signal: find who issued the destroy in the Drydock log."],"tags":["drydock","phabricator","lease","state","destroyed","cli"],"backgroundTag":"invalid-resource-state","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}