phacility/phabricator · warning · Exception

This order can not be refunded because the application has n

Error message

This order can not be refunded because the application has not finished building it yet.

What it means

assertCanRefundOrder() throws when the cart is still STATUS_BUILDING: the application has not finished constructing the order, so no money has moved and there is nothing to refund. This mirrors the cancel guard and is paired with canRefundOrder() for non-throwing checks.

Source

Thrown at src/applications/phortune/storage/PhortuneCart.php:530

    switch ($this->getStatus()) {
      case self::STATUS_BUILDING:
        throw new Exception(
          pht(
            'This order can not be cancelled because the application has not '.
            'finished building it yet.'));
      case self::STATUS_READY:
        throw new Exception(
          pht(
            'This order can not be cancelled because it has not been placed.'));
    }

    return $this->getImplementation()->assertCanCancelOrder($this);
  }

  public function assertCanRefundOrder() {
    switch ($this->getStatus()) {
      case self::STATUS_BUILDING:
        throw new Exception(
          pht(
            'This order can not be refunded because the application has not '.
            'finished building it yet.'));
      case self::STATUS_READY:
        throw new Exception(
          pht(
            'This order can not be refunded because it has not been placed.'));
    }

    return $this->getImplementation()->assertCanRefundOrder($this);
  }

  public function assertCanVoidOrder() {
    if (!$this->getIsInvoice()) {
      throw new Exception(
        pht(
          'This order can not be voided because it is not an invoice.'));
    }

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Gate refund actions on $cart->canRefundOrder() and only show them for placed orders.
  2. Let the cart finish building and be purchased before exposing refund operations.
  3. Filter BUILDING carts out of any order list that offers refund actions.
Defensive patterns

Strategy: validation

Validate before calling

if (!$cart->canRefundOrder()) {
  // cart still building: nothing has been charged, nothing to refund
  return $this->newDialog()->setTitle(pht('Unable to Refund Order'));
}

Type guard

function isRefundableCart(PhortuneCart $cart) {
  return $cart->canRefundOrder();
}

Prevention

When it happens

Trigger: Calling assertCanRefundOrder() (directly or via a refund controller) on a cart whose status is PhortuneCart::STATUS_BUILDING.

Common situations: Refund links or buttons rendered on order lists that include carts still under construction; automated refund tooling that does not filter by status.

Related errors


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