phacility/phabricator · error · Exception
Failed to load build plan ("%s").
Error message
Failed to load build plan ("%s"). What it means
HarbormasterBuildable::applyBuildPlans() receives build requests, each naming a build plan PHID, loads all plans in one query, and throws if any request's plan fails to load. Since the viewer is omnipotent, a miss means the plan row no longer exists — a HarbormasterBuildRequest is referencing a deleted build plan. Note that disabled plans are handled separately (skipped), so this is strictly about missing plans.
Source
Thrown at src/applications/harbormaster/storage/HarbormasterBuildable.php:106
$buildable = self::createOrLoadExisting(
$viewer,
$phid,
$container_phid);
$plan_phids = mpull($requests, 'getBuildPlanPHID');
$plans = id(new HarbormasterBuildPlanQuery())
->setViewer($viewer)
->withPHIDs($plan_phids)
->execute();
$plans = mpull($plans, null, 'getPHID');
foreach ($requests as $request) {
$plan_phid = $request->getBuildPlanPHID();
$plan = idx($plans, $plan_phid);
if (!$plan) {
throw new Exception(
pht(
'Failed to load build plan ("%s").',
$plan_phid));
}
if ($plan->isDisabled()) {
// TODO: This should be communicated more clearly -- maybe we should
// create the build but set the status to "disabled" or "derelict".
continue;
}
$parameters = $request->getBuildParameters();
$buildable->applyPlan($plan, $parameters, $request->getInitiatorPHID());
}
}
public function applyPlan(
HarbormasterBuildPlan $plan,View on GitHub (pinned to 5720a38cfe)
Solutions
- Identify the dangling request: search harbormaster_buildrequest for the failing plan PHID and delete the orphaned rows (the buildable can then be re-triggered).
- Update or delete the Herald rule / automation that still selects the deleted plan so new requests stop referencing it.
- If the plan was deleted in error, restore it from a backup so pending requests can be processed.
- After cleanup, re-run the daemon task or re-trigger the build (e.g. 'Request Build' / add a comment) to confirm builds start.
Defensive patterns
Strategy: validation
Validate before calling
// Before processing build requests, drop or fix requests whose plan is gone:
$plan_phids = mpull($requests, 'getBuildPlanPHID');
$plans = id(new HarbormasterBuildPlanQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withPHIDs($plan_phids)
->execute();
foreach ($requests as $request) {
if (empty($plans[$request->getBuildPlanPHID()])) {
// orphaned request - delete it instead of letting applyBuildPlans throw
}
} Prevention
- When deleting a build plan, also update Herald rules and clean pending build requests that reference it.
- Audit Herald 'Add build plan' actions before removing plans.
- Back up harbormaster_buildplan tables before bulk deletions.
When it happens
Trigger: A build request was created for a plan, and the plan was deleted before the request was processed (e.g. revision created, Herald applied a plan, plan deleted, daemon then runs applyBuildPlans). The exception surfaces in the worker task that starts builds for the buildable.
Common situations: Deleting build plans that are still selected by Herald rules or referenced by queued build requests; plan deleted via CLI/scripts without cleaning up requests; stale harbormaster_buildrequest rows after imports.
Related errors
- Invalid or unknown object ("%s") for land operation, expecte
- Use %s to specify a build plan to run.
- Build plan "%s" does not exist.
- Object "%s" is not a HarbormasterBuildable (it is a "%s"). N
- Choose a build log to rebuild with "--id", or rebuild all lo
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/3a3d00462c950cfe.
Report an issue: GitHub.