{"record":{"id":"e03ea0c3c59224a9","repo":"phacility/phabricator","slug":"specify-a-billing-range-with-s-and-s-or-use-s","errorCode":null,"errorMessage":"Specify a billing range with %s and %s, or use %s.","messagePattern":"Specify a billing range with (.+?) and (.+?), or use (.+?)\\.","errorType":"console","errorClass":"PhutilArgumentUsageException","httpStatus":null,"severity":"warning","filePath":"src/applications/phortune/management/PhabricatorPhortuneManagementInvoiceWorkflow.php","lineNumber":92,"sourceCode":"    $now = $this->parseTimeArgument($now);\n    if (!$now) {\n      $now = PhabricatorTime::getNow();\n    }\n\n    $time_guard = PhabricatorTime::pushTime($now, date_default_timezone_get());\n\n    $console->writeOut(\n      \"%s\\n\",\n      pht(\n        'Set current time to %s.',\n        phabricator_datetime(PhabricatorTime::getNow(), $viewer)));\n\n    $auto_range = $args->getArg('auto-range');\n    $last_arg = $args->getArg('last');\n    $next_arg = $args->getArg('next');\n\n    if (!$auto_range && !$last_arg && !$next_arg) {\n      throw new PhutilArgumentUsageException(\n        pht(\n          'Specify a billing range with %s and %s, or use %s.',\n          '--last',\n          '--next',\n          '--auto-range'));\n    } else if (!$auto_range & (!$last_arg || !$next_arg)) {\n      throw new PhutilArgumentUsageException(\n        pht(\n          'When specifying %s or %s, you must specify both arguments '.\n          'to define the beginning and end of the billing range.',\n          '--last',\n          '--next'));\n    } else if (!$auto_range && ($last_arg && $next_arg)) {\n      $last_time = $this->parseTimeArgument($args->getArg('last'));\n      $next_time = $this->parseTimeArgument($args->getArg('next'));\n    } else if ($auto_range && ($last_arg || $next_arg)) {\n      throw new PhutilArgumentUsageException(\n        pht(","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/phortune/management/PhabricatorPhortuneManagementInvoiceWorkflow.php#L74-L110","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\n$ ./bin/phortune invoice --subscription PHID-PSUB-1234abcd\n\n# after\n$ ./bin/phortune invoice --subscription PHID-PSUB-1234abcd --auto-range\n# or\n$ ./bin/phortune invoice --subscription PHID-PSUB-1234abcd --last 1690000000 --next 1692600000","handlingStrategy":"validation","validationCode":"// Enforce a complete range spec before invoking.\n$has_auto = (bool) $auto_range;\n$has_both = ((bool) $last_epoch) && ((bool) $next_epoch);\nif (!$has_auto && !$has_both) {\n  throw new InvalidArgumentException(\n    'phortune invoice needs either --auto-range or both --last and --next.');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["php","phabricator","phortune","cli","usage-error","billing"],"backgroundTag":"missing-cli-argument","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}