phacility/phabricator · warning · Exception
Refusing to generate a subscription invoice for a billing pe
Error message
Refusing to generate a subscription invoice for a billing period which ends in the future.
What it means
A safety valve in the billing worker: unless the task data carries the manual flag, it refuses to invoice a period whose end (this_epoch) is still in the future. Unlike its sibling errors this is a plain Exception, so the queue treats it as a temporary failure and retries with backoff; it self-heals once the period actually elapses.
Source
Thrown at src/applications/phortune/worker/PhortuneSubscriptionWorker.php:254
$last_epoch = $subscription->getDateCreated();
}
$this_epoch = idx($data, 'trigger.this-epoch');
if (!$last_epoch || !$this_epoch) {
throw new PhabricatorWorkerPermanentFailureException(
pht('Subscription is missing billing period information.'));
}
$period_length = ($this_epoch - $last_epoch);
if ($period_length <= 0) {
throw new PhabricatorWorkerPermanentFailureException(
pht(
'Subscription has invalid billing period.'));
}
if (empty($data['manual'])) {
if (PhabricatorTime::getNow() < $this_epoch) {
throw new Exception(
pht(
'Refusing to generate a subscription invoice for a billing period '.
'which ends in the future.'));
}
}
return array($last_epoch, $this_epoch);
}
}
View on GitHub (pinned to 5720a38cfe)
Solutions
- Wait: the task retries automatically and succeeds once the current time passes this_epoch
- Fix clock skew and keep date.timezone consistent across web and daemon hosts
- To invoice early on purpose, use the subscription's invoice-now action, which queues the task with the manual flag set
Example fix
// before: firing the worker for a period that has not elapsed
$data = array('subscriptionPHID' => $subscription->getPHID());
// after: mark the run as manual to permit early invoicing
$data = array(
'subscriptionPHID' => $subscription->getPHID(),
'manual' => true,
); Defensive patterns
Strategy: retry
Try / catch
try {
// invoke subscription billing manually
} catch (Exception $ex) {
if (strpos($ex->getMessage(), 'ends in the future') !== false) {
// Temporary by design: reschedule the run for $this_epoch; do not alert.
}
} Prevention
- Let the daemon retry: the task succeeds once the period elapses
- Use the invoice-now action (manual flag) when early invoicing is intentional
- Keep scheduling and executing hosts time-synced to avoid firing before the window closes
When it happens
Trigger: The trigger fires before this_epoch has passed (scheduler race, clock skew between the scheduling and executing hosts), or someone fires the worker early without setting data['manual'].
Common situations: Clock drift between hosts in multi-server installs; testing billing with artificially shifted clocks; trying to invoice early by invoking the worker directly instead of the UI action.
Related errors
- Subscription has invalid billing period.
- All members of the account ("%s") for this subscription ("%s
- Unable to load any of the members of the account ("%s") for
- The account ("%s") for this subscription ("%s") has no membe
- Failed to load subscription with PHID "%s".
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/83cd0266871128da.
Report an issue: GitHub.