phacility/phabricator · warning · PhutilArgumentUsageException

Build plan "%s" does not exist.

Error message

Build plan "%s" does not exist.

What it means

The --plan value passed to `harbormaster build` was used to load a HarbormasterBuildPlan by ID and no plan with that ID exists. The value must be the numeric plan ID (from the plan's URI), not the plan name and not a PHID.

Source

Thrown at src/applications/harbormaster/management/HarbormasterManagementBuildWorkflow.php:69

    if (!($buildable instanceof HarbormasterBuildableInterface)) {
      throw new PhutilArgumentUsageException(
        pht('Object "%s" is not a buildable!', $name));
    }

    $plan_id = $args->getArg('plan');
    if (!$plan_id) {
      throw new PhutilArgumentUsageException(
        pht(
          'Use %s to specify a build plan to run.',
          '--plan'));
    }

    $plan = id(new HarbormasterBuildPlanQuery())
      ->setViewer($viewer)
      ->withIDs(array($plan_id))
      ->executeOne();
    if (!$plan) {
      throw new PhutilArgumentUsageException(
        pht('Build plan "%s" does not exist.', $plan_id));
    }

    if (!$plan->canRunManually()) {
      throw new PhutilArgumentUsageException(
        pht('This build plan can not be run manually.'));
    }

    $console = PhutilConsole::getConsole();

    $buildable = HarbormasterBuildable::initializeNewBuildable($viewer)
      ->setIsManualBuildable(true)
      ->setBuildablePHID($buildable->getHarbormasterBuildablePHID())
      ->setContainerPHID($buildable->getHarbormasterContainerPHID())
      ->save();

    $buildable->sendMessage(
      $viewer,

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Open Build > Build Plans in the UI and use the numeric ID from the plan URL (e.g. 5 from /harbormaster/plan/5/).
  2. Confirm the plan still exists and was not deleted.
  3. Quote/trim the value in scripts to avoid stray characters.

Example fix

# before
./bin/phabricator harbormaster build --plan 'Lint and Test' D123

# after
./bin/phabricator harbormaster build --plan 5 D123
Defensive patterns

Strategy: validation

Validate before calling

$plan = id(new HarbormasterBuildPlanQuery())
  ->setViewer($viewer)
  ->withIDs(array((int)$plan_id))
  ->executeOne();
if (!$plan) { /* wrong ID; look it up in the UI before running */ }

Type guard

function planIdExists($viewer, $id) {
  return (bool)id(new HarbormasterBuildPlanQuery())
    ->setViewer($viewer)
    ->withIDs(array((int)$id))
    ->executeOne();
}

Prevention

When it happens

Trigger: Passing a plan name or monogram instead of the numeric ID; a plan that was deleted; copy-pasting an ID from another install; leading zeros/whitespace corrupting the value.

Common situations: Assuming the plan name works; environments where plans were recreated with new IDs and scripts still reference old ones.

Related errors


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