{"record":{"id":"95b923ca1539c67f","repo":"phacility/phabricator","slug":"harbormaster-build-target-s-is-not-a-buildkite","errorCode":null,"errorMessage":"Harbormaster build target \"%s\" is not a Buildkite build step. Only Buildkite steps may be updated via the Buildkite hook.","messagePattern":"Harbormaster build target \"(.+?)\" is not a Buildkite build step\\. Only Buildkite steps may be updated via the Buildkite hook\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/harbormaster/controller/HarbormasterBuildkiteHookController.php","lineNumber":59,"sourceCode":"    }\n\n    $viewer = PhabricatorUser::getOmnipotentUser();\n    $target = id(new HarbormasterBuildTargetQuery())\n      ->setViewer($viewer)\n      ->withPHIDs(array($target_phid))\n      ->needBuildSteps(true)\n      ->executeOne();\n    if (!$target) {\n      throw new Exception(\n        pht(\n          'Harbormaster build target \"%s\" does not exist.',\n          $target_phid));\n    }\n\n    $step = $target->getBuildStep();\n    $impl = $step->getStepImplementation();\n    if (!($impl instanceof HarbormasterBuildkiteBuildStepImplementation)) {\n      throw new Exception(\n        pht(\n          'Harbormaster build target \"%s\" is not a Buildkite build step. '.\n          'Only Buildkite steps may be updated via the Buildkite hook.',\n          $target_phid));\n    }\n\n    $webhook_token = $impl->getSetting('webhook.token');\n    $request_token = $request->getHTTPHeader('X-Buildkite-Token');\n\n    if (!phutil_hashes_are_identical($webhook_token, $request_token)) {\n      throw new Exception(\n        pht(\n          'Buildkite request to target \"%s\" had the wrong authentication '.\n          'token. The Buildkite pipeline and Harbormaster build step must '.\n          'be configured with the same token.',\n          $target_phid));\n    }\n","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/harbormaster/controller/HarbormasterBuildkiteHookController.php#L41-L77","documentation":"The target PHID from the Buildkite webhook resolved to a real HarbormasterBuildTarget, but its build step's implementation is not HarbormasterBuildkiteBuildStepImplementation. The hook refuses to mutate targets that were not created by a Buildkite step, since only those steps own the webhook contract (token settings, state mapping) the controller applies.","triggerScenarios":"A buildTargetPHID belonging to a CircleCI, HTTP request, script, or other step type reaching the Buildkite hook; a plan that was edited so the step changed implementation while an old Buildkite delivery arrived; the same PHID mistakenly reused in a test payload.","commonSituations":"Mixing up webhook URLs between the CircleCI hook and the Buildkite hook; replaying an old webhook after the plan's step was replaced; pipelines configured with a PHID from a different step in the same plan.","solutions":["Confirm the build target PHID actually belongs to a Buildkite step (check the build plan in the UI: the step must be a 'Buildkite' step).","Make sure the Buildkite pipeline's meta-data carries the PHID of the Buildkite step's target, not another step's target in the same build.","Trigger a fresh build so each step's own webhook contract is used."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"$impl = $target->getBuildStep()->getStepImplementation();\nif (!($impl instanceof HarbormasterBuildkiteBuildStepImplementation)) {\n  // this delivery belongs to a different hook; route accordingly\n}","typeGuard":"function isBuildkiteTarget(HarbormasterBuildTarget $target) {\n  return $target->getBuildStep()->getStepImplementation()\n    instanceof HarbormasterBuildkiteBuildStepImplementation;\n}","tryCatchPattern":null,"preventionTips":["Give each CI provider its own webhook URL and never reuse a target PHID between steps.","When editing plans that mid-flight builds use, expect late webhooks for replaced steps and drop them gracefully.","Assert step type before applying external state in any custom webhook glue."],"tags":["harbormaster","buildkite","webhook","step-type-mismatch"],"backgroundTag":"webhook-target-type-mismatch","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}