phacility/phabricator · error · PhabricatorWorkerPermanentFailureException

No such lease "%s"!

Error message

No such lease "%s"!

What it means

DrydockWorker::loadLease() loads a lease by PHID using the omnipotent user; if no DrydockLease row matches, it throws a PhabricatorWorkerPermanentFailureException so the queued task fails permanently instead of retrying. The placeholder is the lease PHID the task was carrying.

Source

Thrown at src/applications/drydock/worker/DrydockWorker.php:17

<?php

abstract class DrydockWorker extends PhabricatorWorker {

  protected function getViewer() {
    return PhabricatorUser::getOmnipotentUser();
  }

  protected function loadLease($lease_phid) {
    $viewer = $this->getViewer();

    $lease = id(new DrydockLeaseQuery())
      ->setViewer($viewer)
      ->withPHIDs(array($lease_phid))
      ->executeOne();
    if (!$lease) {
      throw new PhabricatorWorkerPermanentFailureException(
        pht('No such lease "%s"!', $lease_phid));
    }

    return $lease;
  }

  protected function loadResource($resource_phid) {
    $viewer = $this->getViewer();

    $resource = id(new DrydockResourceQuery())
      ->setViewer($viewer)
      ->withPHIDs(array($resource_phid))
      ->executeOne();
    if (!$resource) {
      throw new PhabricatorWorkerPermanentFailureException(
        pht('No such resource "%s"!', $resource_phid));
    }

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Verify the lease exists: search the PHID in the Drydock lease UI or run a DrydockLeaseQuery with the omnipotent user.
  2. If the lease was legitimately released/destroyed, archive the failed task — the permanent failure is the correct outcome and nothing is stuck.
  3. Check the Drydock garbage collector configuration if leases disappear while tasks about them are still queued.
  4. If the PHID never existed, audit the code path that queued the task to find where the bogus PHID comes from.
Defensive patterns

Strategy: validation

Validate before calling

$lease = id(new DrydockLeaseQuery())
  ->setViewer(PhabricatorUser::getOmnipotentUser())
  ->withPHIDs(array($lease_phid))
  ->executeOne();
if (!$lease) {
  // do not queue work for a lease that does not exist
  return;

Prevention

When it happens

Trigger: Any drydock worker task (lease update, operation worker) calls loadLease($phid) with a lease PHID that does not exist in the database: the lease was released, garbage-collected, or destroyed after the task was queued, or the PHID is malformed/typo'd.

Common situations: Lease expires and is reclaimed by the Drydock garbage collector between task queueing and execution; leases manually deleted via CLI/UI; stale queued tasks after rebuilding drydock storage; task data referencing a lease from another environment.

Related errors


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