phacility/phabricator · warning · PhutilArgumentUsageException

Object " " is not a Harbormaster Buildable!

Error message

Object "%s" is not a Harbormaster Buildable!

What it means

Thrown by 'bin/harbormaster update'. The supplied name resolved to a real object, but that object is not a HarbormasterBuildable (for example a Differential revision or a Maniphest task). Because update drives buildable state, it rejects objects of any other type immediately after the generic object query.

Solutions

  1. Pass the buildable monogram (B...) shown on the build page
  2. When scripting from a revision or commit, first resolve its buildables via harbormaster.buildable.search with objectPHIDs, then update those

Example fix

# before
$ bin/harbormaster update D123
# after
$ bin/harbormaster update B123
Defensive patterns

Strategy: type-guard

Validate before calling

$buildable = id(new PhabricatorObjectQuery())
  ->setViewer($viewer)
  ->withNames(array($name))
  ->executeOne();
if ($buildable && !($buildable instanceof HarbormasterBuildable)) {
  // wrong object type; resolve the real buildable instead
}

Type guard

function isHarbormasterBuildable($object) {
  return ($object instanceof HarbormasterBuildable);
}

Prevention

When it happens

Trigger: Running 'bin/harbormaster update D123' or 'bin/harbormaster update T123'; passing a PHID whose type is not PHID-HMBB-.

Common situations: Confusing the object being built (a commit/revision) with its buildable; scripts resolving names generically and forwarding them without a type check.

Related errors


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

Appendix: source

Thrown at src/applications/harbormaster/management/HarbormasterManagementUpdateWorkflow.php:59

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

    $buildable = id(new PhabricatorObjectQuery())
      ->setViewer($viewer)
      ->withNames($names)
      ->executeOne();

    if (!$buildable) {
      throw new PhutilArgumentUsageException(
        pht('No such buildable "%s"!', head($names)));
    }

    if (!($buildable instanceof HarbormasterBuildable)) {
      throw new PhutilArgumentUsageException(
        pht('Object "%s" is not a Harbormaster Buildable!', head($names)));
    }

    // Reload the buildable directly to get builds.
    $buildable = id(new HarbormasterBuildableQuery())
      ->setViewer($viewer)
      ->withIDs(array($buildable->getID()))
      ->needBuilds(true)
      ->executeOne();

    $builds = $buildable->getBuilds();
    $builds = mpull($builds, null, 'getID');

    $build_id = $args->getArg('build');
    if ($build_id) {
      $builds = array_select_keys($builds, array($build_id));
      if (!$builds) {
        throw new PhutilArgumentUsageException(

View on GitHub (pinned to 5720a38cfe)