phacility/phabricator · warning · PhutilArgumentUsageException

Use either %s or %s and %s to specify the billing range, but

Error message

Use either %s or %s and %s to specify the billing range, but not both.

What it means

PhutilArgumentUsageException thrown by the phortune invoice workflow when --auto-range is combined with --last and/or --next. The two range mechanisms are mutually exclusive: --auto-range derives the window from the subscription's trigger event, while --last/--next state it explicitly. Mixing them is contradictory, and honoring both could double-bill, so the workflow aborts.

Source

Thrown at src/applications/phortune/management/PhabricatorPhortuneManagementInvoiceWorkflow.php:109

    if (!$auto_range && !$last_arg && !$next_arg) {
      throw new PhutilArgumentUsageException(
        pht(
          'Specify a billing range with %s and %s, or use %s.',
          '--last',
          '--next',
          '--auto-range'));
    } else if (!$auto_range & (!$last_arg || !$next_arg)) {
      throw new PhutilArgumentUsageException(
        pht(
          'When specifying %s or %s, you must specify both arguments '.
          'to define the beginning and end of the billing range.',
          '--last',
          '--next'));
    } else if (!$auto_range && ($last_arg && $next_arg)) {
      $last_time = $this->parseTimeArgument($args->getArg('last'));
      $next_time = $this->parseTimeArgument($args->getArg('next'));
    } else if ($auto_range && ($last_arg || $next_arg)) {
      throw new PhutilArgumentUsageException(
        pht(
          'Use either %s or %s and %s to specify the '.
          'billing range, but not both.',
          '--auto-range',
          '--last',
          '--next'));
    } else {
      $trigger = $subscription->getTrigger();
      $event = $trigger->getEvent();
      if (!$event) {
        throw new PhutilArgumentUsageException(
          pht(
            'Unable to calculate %s, this subscription has not been '.
            'scheduled for billing yet. Wait for the trigger daemon to '.
            'schedule the subscription.',
            '--auto-range'));
      }
      $last_time = $event->getLastEventEpoch();

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Remove --auto-range and keep the explicit --last/--next pair, or remove both --last and --next and keep --auto-range.
  2. Audit wrapper scripts and runbooks for stale flags after switching range strategies.
  3. If you only need to shift the whole period, adjust --last/--next together rather than layering --auto-range.

Example fix

# before
$ ./bin/phortune invoice --subscription PHID-PSUB-1234abcd --auto-range --last 1690000000

# after
$ ./bin/phortune invoice --subscription PHID-PSUB-1234abcd --last 1690000000 --next 1692600000
Defensive patterns

Strategy: validation

Validate before calling

// The two range mechanisms are mutually exclusive.
if ($auto_range && ($last_epoch || $next_epoch)) {
  throw new InvalidArgumentException(
    'Pass either --auto-range OR --last/--next, never both.');
}

Prevention

When it happens

Trigger: Running `... --auto-range --last 1690000000`, `... --auto-range --next 1692600000`, or all three flags together. Condition: ($auto_range && ($last_arg || $next_arg)).

Common situations: Copy-paste accretion in wrapper scripts where --auto-range was added on top of old explicit ranges; cautious operators hedging by specifying both 'to be safe', which is exactly the ambiguity the check forbids.

Related errors


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