phacility/phabricator · warning · PhutilArgumentUsageException
Specify a billing range with %s and %s, or use %s.
Error message
Specify a billing range with %s and %s, or use %s.
What it means
PhutilArgumentUsageException thrown by the phortune invoice workflow when none of --auto-range, --last, or --next is supplied. The workflow refuses to guess a billing range because an incorrect range can double-bill customers; the developer must either let the trigger schedule compute the range (--auto-range) or give the epoch range explicitly with both --last and --next.
Source
Thrown at src/applications/phortune/management/PhabricatorPhortuneManagementInvoiceWorkflow.php:92
$now = $this->parseTimeArgument($now);
if (!$now) {
$now = PhabricatorTime::getNow();
}
$time_guard = PhabricatorTime::pushTime($now, date_default_timezone_get());
$console->writeOut(
"%s\n",
pht(
'Set current time to %s.',
phabricator_datetime(PhabricatorTime::getNow(), $viewer)));
$auto_range = $args->getArg('auto-range');
$last_arg = $args->getArg('last');
$next_arg = $args->getArg('next');
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(View on GitHub (pinned to 5720a38cfe)
Solutions
- Pass --auto-range to let the subscription's trigger event define the range (requires the subscription to already be scheduled).
- Or pass both --last <epoch> and --next <epoch> to define the billing window explicitly.
- Encode the chosen form in your runbook/script so every invocation includes a complete range specification.
Example fix
# before $ ./bin/phortune invoice --subscription PHID-PSUB-1234abcd # after $ ./bin/phortune invoice --subscription PHID-PSUB-1234abcd --auto-range # or $ ./bin/phortune invoice --subscription PHID-PSUB-1234abcd --last 1690000000 --next 1692600000
Defensive patterns
Strategy: validation
Validate before calling
// Enforce a complete range spec before invoking.
$has_auto = (bool) $auto_range;
$has_both = ((bool) $last_epoch) && ((bool) $next_epoch);
if (!$has_auto && !$has_both) {
throw new InvalidArgumentException(
'phortune invoice needs either --auto-range or both --last and --next.');
} Prevention
- Template the invoice command with a placeholder for the range flags so it is never omitted.
- Prefer --auto-range for routine re-invoicing; reserve --last/--next for reconstructing a specific period.
- Remember the workflow refuses to guess a range by design — it guards against double billing.
When it happens
Trigger: Running `bin/phortune invoice --subscription <PHID>` with no range flags. The check is (!$auto_range && !$last_arg && !$next_arg), so any single stray flag like only --next also lands here only if the others are absent — with exactly one of --last/--next you get the companion error instead.
Common situations: Assuming the script defaults to the current billing period; building cron wrappers that only pass the subscription; upgrading from an older workflow that had no explicit range concept.
Related errors
- Specify which subscription to invoice with %s.
- When specifying %s or %s, you must specify both arguments to
- Use either %s or %s and %s to specify the billing range, but
- Unable to load subscription with PHID "%s".
- Unable to calculate %s, this subscription has not been sched
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/e03ea0c3c59224a9.
Report an issue: GitHub.