{"record":{"id":"5aabeb36c9761bbd","repo":"phacility/phabricator","slug":"you-can-not-promote-an-entire-service-s","errorCode":null,"errorMessage":"You can not \"--promote\" an entire service (\"%s\"). Only a single device may be promoted.","messagePattern":"You can not \"--promote\" an entire service \\(\"(.+?)\"\\)\\. Only a single device may be promoted\\.","errorType":"exception","errorClass":"PhutilArgumentUsageException","httpStatus":null,"severity":"error","filePath":"src/applications/repository/management/PhabricatorRepositoryManagementThawWorkflow.php","lineNumber":83,"sourceCode":"    $target_name = nonempty($promote, $demote);\n\n    $devices = id(new AlmanacDeviceQuery())\n      ->setViewer($viewer)\n      ->withNames(array($target_name))\n      ->execute();\n    if (!$devices) {\n      $service = id(new AlmanacServiceQuery())\n        ->setViewer($viewer)\n        ->withNames(array($target_name))\n        ->executeOne();\n\n      if (!$service) {\n        throw new PhutilArgumentUsageException(\n          pht('No device or service named \"%s\" exists.', $target_name));\n      }\n\n      if ($promote) {\n        throw new PhutilArgumentUsageException(\n          pht(\n            'You can not \"--promote\" an entire service (\"%s\"). Only a single '.\n            'device may be promoted.',\n            $target_name));\n      }\n\n      $bindings = id(new AlmanacBindingQuery())\n        ->setViewer($viewer)\n        ->withServicePHIDs(array($service->getPHID()))\n        ->execute();\n      if (!$bindings) {\n        throw new PhutilArgumentUsageException(\n          pht(\n            'Service \"%s\" is not bound to any devices.',\n            $target_name));\n      }\n\n      $interfaces = id(new AlmanacInterfaceQuery())","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/repository/management/PhabricatorRepositoryManagementThawWorkflow.php#L65-L101","documentation":"thaw can `--demote` an entire Almanac service (discarding every version in it at once), but `--promote` must name a single device: promoting makes one device's version authoritative, which is meaningless for a multi-device aggregate. When the resolved target is a service and `--promote` was used, the workflow rejects it with this PhutilArgumentUsageException.","triggerScenarios":"Running `./bin/repository thaw --promote <service-name>` where the name resolves to an Almanac service rather than a device — e.g. promoting the repository cluster service itself.","commonSituations":"Operators pasting the service name (the object most visible in the cluster UI) instead of one of its bound devices during an unfreeze incident.","solutions":["Promote a specific device bound to that service instead: list the service's bindings/devices in the Almanac console and pass that device's name.","If you truly meant to discard versions wholesale, that is `--demote <service>`, not promote."],"exampleFix":"# before\n./bin/repository thaw --promote repo-cluster   # Almanac service name\n# Usage exception: You can not \"--promote\" an entire service (\"repo-cluster\")...\n\n# after: promote one device bound to the service\n./bin/repository thaw --promote repo-host-01","handlingStrategy":"validation","validationCode":"# Ensure the promote target is a device, not a service\nname='repo-host-01'\nservices=$(mysql -N -B phabricator_almanac -e \\\n  \"SELECT COUNT(*) FROM almanac_service WHERE name = '$name'\")\n[ \"$services\" -eq 0 ] || { echo \"cannot --promote a service; promote one of its devices\" >&2; exit 1; }\n./bin/repository thaw --promote \"$name\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Remember the asymmetry: `--demote` accepts a service, `--promote` accepts only a single device.","When resolving a service during an incident, pick the specific bound device whose copy is authoritative."],"tags":["php","phabricator","cli","thaw","almanac","clustering","invalid-target"],"backgroundTag":"invalid-promotion-target","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}