{"record":{"id":"f58f25fa0fc6562c","repo":"phacility/phabricator","slug":"use-either-s-or-s-and-s-to-specify-the-billing","errorCode":null,"errorMessage":"Use either %s or %s and %s to specify the billing range, but not both.","messagePattern":"Use either (.+?) or (.+?) and (.+?) to specify the billing range, but not both\\.","errorType":"console","errorClass":"PhutilArgumentUsageException","httpStatus":null,"severity":"warning","filePath":"src/applications/phortune/management/PhabricatorPhortuneManagementInvoiceWorkflow.php","lineNumber":109,"sourceCode":"    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(\n          'Use either %s or %s and %s to specify the '.\n          'billing range, but not both.',\n          '--auto-range',\n          '--last',\n          '--next'));\n    } else {\n      $trigger = $subscription->getTrigger();\n      $event = $trigger->getEvent();\n      if (!$event) {\n        throw new PhutilArgumentUsageException(\n          pht(\n            'Unable to calculate %s, this subscription has not been '.\n            'scheduled for billing yet. Wait for the trigger daemon to '.\n            'schedule the subscription.',\n            '--auto-range'));\n      }\n      $last_time = $event->getLastEventEpoch();","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/phortune/management/PhabricatorPhortuneManagementInvoiceWorkflow.php#L91-L127","documentation":"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.","triggerScenarios":"Running `... --auto-range --last 1690000000`, `... --auto-range --next 1692600000`, or all three flags together. Condition: ($auto_range && ($last_arg || $next_arg)).","commonSituations":"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.","solutions":["Remove --auto-range and keep the explicit --last/--next pair, or remove both --last and --next and keep --auto-range.","Audit wrapper scripts and runbooks for stale flags after switching range strategies.","If you only need to shift the whole period, adjust --last/--next together rather than layering --auto-range."],"exampleFix":"# before\n$ ./bin/phortune invoice --subscription PHID-PSUB-1234abcd --auto-range --last 1690000000\n\n# after\n$ ./bin/phortune invoice --subscription PHID-PSUB-1234abcd --last 1690000000 --next 1692600000","handlingStrategy":"validation","validationCode":"// The two range mechanisms are mutually exclusive.\nif ($auto_range && ($last_epoch || $next_epoch)) {\n  throw new InvalidArgumentException(\n    'Pass either --auto-range OR --last/--next, never both.');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Audit wrapper scripts when switching between auto and explicit ranges — delete the old flags.","Adding flags 'for safety' is the exact anti-pattern this error guards against."],"tags":["php","phabricator","phortune","cli","usage-error","conflicting-arguments","billing"],"backgroundTag":"conflicting-cli-arguments","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}