phacility/phabricator · warning · PhutilArgumentUsageException

Specify either --promote or --demote, but not both.

Error message

Specify either --promote or --demote, but not both.

What it means

thaw's `--promote` (accept a device's version of the repository) and `--demote` (reject it) are opposite operations on the same target, so exactly one must be given. Supplying both is contradictory and rejected with this PhutilArgumentUsageException before any Almanac query runs.

Source

Thrown at src/applications/repository/management/PhabricatorRepositoryManagementThawWorkflow.php:61

            'name' => 'repositories',
            'wildcard' => true,
          ),
        ));
  }

  public function execute(PhutilArgumentParser $args) {
    $viewer = $this->getViewer();

    $promote = $args->getArg('promote');
    $demote = $args->getArg('demote');

    if (!$promote && !$demote) {
      throw new PhutilArgumentUsageException(
        pht('You must choose a device to --promote or --demote.'));
    }

    if ($promote && $demote) {
      throw new PhutilArgumentUsageException(
        pht('Specify either --promote or --demote, but not both.'));
    }

    $target_name = nonempty($promote, $demote);

    $devices = id(new AlmanacDeviceQuery())
      ->setViewer($viewer)
      ->withNames(array($target_name))
      ->execute();
    if (!$devices) {
      $service = id(new AlmanacServiceQuery())
        ->setViewer($viewer)
        ->withNames(array($target_name))
        ->executeOne();

      if (!$service) {
        throw new PhutilArgumentUsageException(
          pht('No device or service named "%s" exists.', $target_name));

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Keep exactly one operation per invocation: `--promote <device>` to trust its version, or `--demote <device>` to discard it.
  2. Run the two operations as separate sequential commands if both are genuinely needed.

Example fix

# before
./bin/repository thaw --promote repo-01 --demote repo-02
# Usage exception: Specify either --promote or --demote, but not both.

# after: two separate invocations
./bin/repository thaw --demote repo-02
./bin/repository thaw --promote repo-01
Defensive patterns

Strategy: validation

Validate before calling

# Allow exactly one operation
if [ -n "$PROMOTE" ] && [ -n "$DEMOTE" ]; then
  echo "pass either --promote or --demote, not both" >&2; exit 2
fi
./bin/repository thaw ${PROMOTE:+--promote "$PROMOTE"} ${DEMOTE:+--demote "$DEMOTE"}

Prevention

When it happens

Trigger: Running `./bin/repository thaw --promote <device> --demote <device>` — any invocation where both `$promote` and `$demote` are truthy.

Common situations: Cut-and-paste command assembly from incident runbooks; scripts forwarding both options from unset/overlapping configuration.

Related errors


AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21). Data as JSON: /api/errors/01d643c84cd56ea9. Report an issue: GitHub.