phacility/phabricator · error · Exception

Harbormaster build target "%s" does not exist.

Error message

Harbormaster build target "%s" does not exist.

What it means

The Buildkite webhook resolved a buildTargetPHID from build.meta_data and loaded it with HarbormasterBuildTargetQuery under the omnipotent user, but no build target with that PHID exists. The reference from the external system (Buildkite) to the internal Harbormaster entity is dangling.

Source

Thrown at src/applications/harbormaster/controller/HarbormasterBuildkiteHookController.php:50

      throw new Exception(
        pht(
          'Expected "%s" property to contain a dictionary.',
          'build.meta_data'));
    }

    $target_phid = idx($meta_data, 'buildTargetPHID');
    if (!$target_phid) {
      return $this->newHookResponse(pht('OK: No Harbormaster target PHID.'));
    }

    $viewer = PhabricatorUser::getOmnipotentUser();
    $target = id(new HarbormasterBuildTargetQuery())
      ->setViewer($viewer)
      ->withPHIDs(array($target_phid))
      ->needBuildSteps(true)
      ->executeOne();
    if (!$target) {
      throw new Exception(
        pht(
          'Harbormaster build target "%s" does not exist.',
          $target_phid));
    }

    $step = $target->getBuildStep();
    $impl = $step->getStepImplementation();
    if (!($impl instanceof HarbormasterBuildkiteBuildStepImplementation)) {
      throw new Exception(
        pht(
          'Harbormaster build target "%s" is not a Buildkite build step. '.
          'Only Buildkite steps may be updated via the Buildkite hook.',
          $target_phid));
    }

    $webhook_token = $impl->getSetting('webhook.token');
    $request_token = $request->getHTTPHeader('X-Buildkite-Token');

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Trigger a fresh build from Harbormaster so a new target exists, and make sure the pipeline picks up the new PHID (meta-data is per-build; old deliveries cannot be applied).
  2. Verify the PHID format and install: PHID-HMBT- values are per-instance; a payload from another install will never resolve.
  3. If builds are being GC'd before CI reports, raise the retention for old builds/logs in the garbage collector config.
  4. Ignore the delivery in Buildkite — the error is expected for stale events and the new build will report correctly.
Defensive patterns

Strategy: try-catch

Validate before calling

// Before applying a webhook, confirm the target still exists:
$target = id(new HarbormasterBuildTargetQuery())
  ->setViewer(PhabricatorUser::getOmnipotentUser())
  ->withPHIDs(array($target_phid))
  ->executeOne();
if (!$target) { /* drop the stale delivery */ }

Try / catch

try {
  $this->updateTarget($target, $payload);
} catch (Exception $e) {
  // Stale PHID from an old build: log and acknowledge the delivery,
  // do not retry — the target is gone for good.
  phlog($e);
  return newHookResponse(pht('OK: Stale target.'));
}

Prevention

When it happens

Trigger: A webhook replayed long after the build (and its targets) were garbage-collected or deleted; a stale pipeline configuration carrying an old PHID; a hand-crafted payload with a typo'd or invented PHID; the buildable/plan being rebuilt so old targets vanished while Buildkite still reports for them.

Common situations: Retrying old webhook deliveries from the Buildkite UI; aggressive Harbormaster garbage collection (phabricator garbage-collector) removing old build data; copy-pasting payloads between test and production installs where PHIDs differ.

Related errors


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