{"record":{"id":"44162767e0e9c58e","repo":"phacility/phabricator","slug":"you-must-choose-a-device-to-promote-or-demote","errorCode":null,"errorMessage":"You must choose a device to --promote or --demote.","messagePattern":"You must choose a device to --promote or --demote\\.","errorType":"exception","errorClass":"PhutilArgumentUsageException","httpStatus":null,"severity":"warning","filePath":"src/applications/repository/management/PhabricatorRepositoryManagementThawWorkflow.php","lineNumber":56,"sourceCode":"            'help' => pht(\n              'Apply the promotion or demotion to all repositories hosted '.\n              'on the device.'),\n          ),\n          array(\n            'name' => 'repositories',\n            'wildcard' => true,\n          ),\n        ));\n  }\n\n  public function execute(PhutilArgumentParser $args) {\n    $viewer = $this->getViewer();\n\n    $promote = $args->getArg('promote');\n    $demote = $args->getArg('demote');\n\n    if (!$promote && !$demote) {\n      throw new PhutilArgumentUsageException(\n        pht('You must choose a device to --promote or --demote.'));\n    }\n\n    if ($promote && $demote) {\n      throw new PhutilArgumentUsageException(\n        pht('Specify either --promote or --demote, but not both.'));\n    }\n\n    $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))","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/repository/management/PhabricatorRepositoryManagementThawWorkflow.php#L38-L74","documentation":"`bin/repository thaw` unfreezes clustered repository versions by promoting or demoting a specific device. The command requires exactly one of `--promote <device>` or `--demote <device>`; with neither, there is no thaw operation to perform and the workflow exits with this PhutilArgumentUsageException.","triggerScenarios":"Bare `./bin/repository thaw` invocation, or one with only auxiliary flags (e.g. `--enqueue`) and no `--promote`/`--demote` target.","commonSituations":"Operators unfamiliar with cluster unfreezing exploring the command; scripts where the device name variable expanded to empty so the flag was omitted.","solutions":["Pass a target: `./bin/repository thaw --promote <device>` to make a device's version authoritative, or `--demote <device>` to discard its version.","Quote script variables and check they are non-empty before building the command (`: \"${DEVICE:?device required}\"`).","Read `./bin/repository thaw --help` and the clustering documentation — thawing is for resolving frozen/demoted cluster states."],"exampleFix":"# before\n./bin/repository thaw\n# Usage exception: You must choose a device to --promote or --demote.\n\n# after\n./bin/repository thaw --promote repo-host-01","handlingStrategy":"validation","validationCode":"# Require a promote/demote target with a non-empty device name\n: \"${DEVICE:?thaw requires a device via --promote or --demote}\"\n./bin/repository thaw ${OP:+--$OP \"$DEVICE\"}   # OP is 'promote' or 'demote'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Make the operation and device name mandatory, non-empty variables in thaw wrappers.","Keep an incident runbook that spells out full example thaw commands."],"tags":["php","phabricator","cli","thaw","clustering","usage-error"],"backgroundTag":"missing-required-flag","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}