phacility/phabricator · error · Exception

Trying to activate a resource from the wrong status. Status

Error message

Trying to activate a resource from the wrong status. Status must be "%s", actually "%s".

What it means

DrydockResource::activateResource() enforces the resource state machine: a resource may only move from STATUS_PENDING to active. The exception names both the expected and actual status, so a mismatch means the resource is already active, broken, released, or destroyed. Most commonly this is a double activation or a resource that jumped straight to active during allocation.

Source

Thrown at src/applications/drydock/storage/DrydockResource.php:198

    return $this;
  }

  public function isAllocatedResource() {
    return $this->isAllocated;
  }

  public function activateResource() {
    if (!$this->getID()) {
      throw new Exception(
        pht(
          'Trying to activate a resource which has not yet been persisted.'));
    }

    $expect_status = DrydockResourceStatus::STATUS_PENDING;
    $actual_status = $this->getStatus();
    if ($actual_status != $expect_status) {
      throw new Exception(
        pht(
          'Trying to activate a resource from the wrong status. Status must '.
          'be "%s", actually "%s".',
          $expect_status,
          $actual_status));
    }

    $this->openTransaction();

    try {
      DrydockSlotLock::acquireLocks($this->getPHID(), $this->slotLocks);
      $this->slotLocks = array();
    } catch (DrydockSlotLockException $ex) {
      $this->killTransaction();

      $this->logEvent(
        DrydockSlotLockFailureLogType::LOGCONST,
        array(

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Check $resource->getStatus() == DrydockResourceStatus::STATUS_PENDING before calling activateResource(), and skip if it is already STATUS_ACTIVE.
  2. Reload the resource inside the transaction/lock scope right before activating so you see the committed status, not a stale copy.
  3. If using setActivateWhenAllocated(true), do not also run the separate activation step.

Example fix

// before
$blueprint->activateResource($resource);

// after
if ($resource->getStatus() === DrydockResourceStatus::STATUS_PENDING) {
  $blueprint->activateResource($resource);
}
Defensive patterns

Strategy: validation

Validate before calling

if ($resource->getStatus() !== DrydockResourceStatus::STATUS_PENDING) {
  // already active/broken/released: skip or handle
  return;
}
$resource->activateResource();

Try / catch

try {
  $resource->activateResource();
} catch (Exception $ex) {
  if ($resource->getStatus() === DrydockResourceStatus::STATUS_ACTIVE) {
    return; // lost activation race; already active
  }
  throw $ex;
}

Prevention

When it happens

Trigger: Calling activateResource() twice (e.g. two DrydockResourceUpdateWorker tasks racing or a retry after a partially completed activation); allocating with activateWhenAllocated set so allocateResource() already moved the status to STATUS_ACTIVE, then activating again; activating a resource that a concurrent task broke or released.

Common situations: Duplicate resource-update worker tasks after a task retry; a blueprint whose allocateResource() uses ->setActivateWhenAllocated(true) while the standard update worker also activates; stale copies of a resource object in long-running daemon code.

Related errors


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