{"record":{"id":"a74e31c1a081b56e","repo":"phacility/phabricator","slug":"object-s-is-not-a-harbormaster-buildable","errorCode":null,"errorMessage":"Object \"%s\" is not a Harbormaster Buildable!","messagePattern":"Object \"(.+?)\" is not a Harbormaster Buildable!","errorType":"console","errorClass":"PhutilArgumentUsageException","httpStatus":null,"severity":"warning","filePath":"src/applications/harbormaster/management/HarbormasterManagementUpdateWorkflow.php","lineNumber":59,"sourceCode":"\n    $names = $args->getArg('buildable');\n    if (count($names) != 1) {\n      throw new PhutilArgumentUsageException(\n        pht('Specify exactly one buildable, by object name.'));\n    }\n\n    $buildable = id(new PhabricatorObjectQuery())\n      ->setViewer($viewer)\n      ->withNames($names)\n      ->executeOne();\n\n    if (!$buildable) {\n      throw new PhutilArgumentUsageException(\n        pht('No such buildable \"%s\"!', head($names)));\n    }\n\n    if (!($buildable instanceof HarbormasterBuildable)) {\n      throw new PhutilArgumentUsageException(\n        pht('Object \"%s\" is not a Harbormaster Buildable!', head($names)));\n    }\n\n    // Reload the buildable directly to get builds.\n    $buildable = id(new HarbormasterBuildableQuery())\n      ->setViewer($viewer)\n      ->withIDs(array($buildable->getID()))\n      ->needBuilds(true)\n      ->executeOne();\n\n    $builds = $buildable->getBuilds();\n    $builds = mpull($builds, null, 'getID');\n\n    $build_id = $args->getArg('build');\n    if ($build_id) {\n      $builds = array_select_keys($builds, array($build_id));\n      if (!$builds) {\n        throw new PhutilArgumentUsageException(","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/harbormaster/management/HarbormasterManagementUpdateWorkflow.php#L41-L77","documentation":"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.","triggerScenarios":"Running 'bin/harbormaster update D123' or 'bin/harbormaster update T123'; passing a PHID whose type is not PHID-HMBB-.","commonSituations":"Confusing the object being built (a commit/revision) with its buildable; scripts resolving names generically and forwarding them without a type check.","solutions":["Pass the buildable monogram (B...) shown on the build page","When scripting from a revision or commit, first resolve its buildables via harbormaster.buildable.search with objectPHIDs, then update those"],"exampleFix":"# before\n$ bin/harbormaster update D123\n# after\n$ bin/harbormaster update B123","handlingStrategy":"type-guard","validationCode":"$buildable = id(new PhabricatorObjectQuery())\n  ->setViewer($viewer)\n  ->withNames(array($name))\n  ->executeOne();\nif ($buildable && !($buildable instanceof HarbormasterBuildable)) {\n  // wrong object type; resolve the real buildable instead\n}","typeGuard":"function isHarbormasterBuildable($object) {\n  return ($object instanceof HarbormasterBuildable);\n}","tryCatchPattern":null,"preventionTips":["Pass buildable monograms (B...), not revision/task monograms, to update","In scripts, type-check resolved objects before forwarding them to the CLI"],"tags":["harbormaster","phabricator","cli","wrong-object-type","buildable"],"backgroundTag":"wrong-object-type","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}