phacility/phabricator · warning · PhutilArgumentUsageException

Object " " is not a buildable!

Error message

Object "%s" is not a buildable!

What it means

The name resolved to a real object, but it does not implement HarbormasterBuildableInterface — the marker interface for things Harbormaster can build (revisions, commits, repositories). Anything else (tasks, users, pastes, mocks...) reaches this check and is rejected with the object's name.

Solutions

  1. Pass a buildable object: a Differential revision (D123), a Diffusion commit, or a repository, per Harbormaster's buildable types.
  2. If you need to build a commit, use its monogram/PHID from Diffusion rather than the raw hash alone.
  3. Filter your input list to buildable types before invoking the command.

Example fix

# before
./bin/phabricator harbormaster build --plan 3 T123

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

Strategy: type-guard

Validate before calling

// After resolving the name, before building:
$object = head($query->execute());
if (!($object instanceof HarbormasterBuildableInterface)) {
  // not buildable; skip
}

Type guard

function isBuildableObject($object) {
  return $object instanceof HarbormasterBuildableInterface;
}

Prevention

When it happens

Trigger: Passing a Maniphest monogram (T123), a user PHID, or a Paste P45 to `harbormaster build`; expecting any object to be buildable; scripts that feed arbitrary object names into the command.

Common situations: Assuming 'buildable' means 'anything with a PHID'; automating builds from object lists that include non-buildable types.

Related errors


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

Appendix: source

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

    $names = $args->getArg('buildable');
    if (count($names) != 1) {
      throw new PhutilArgumentUsageException(
        pht('Specify exactly one buildable object, by object name.'));
    }

    $name = head($names);

    $buildable = id(new PhabricatorObjectQuery())
      ->setViewer($viewer)
      ->withNames($names)
      ->executeOne();
    if (!$buildable) {
      throw new PhutilArgumentUsageException(
        pht('No such buildable "%s"!', $name));
    }

    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));

View on GitHub (pinned to 5720a38cfe)