phacility/phabricator · warning · Exception

This order can not be cancelled because the application has

Error message

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

What it means

PhortuneCart::assertCanCancelOrder() throws when the cart is still STATUS_BUILDING: the owning application has not finished adding purchases, so cancelling now would tear down a half-built order. The companion canCancelOrder() catches this and returns false. It is an expected user-facing state check, not corruption.

Source

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

      return true;
    } catch (Exception $ex) {
      return false;
    }
  }

  public function canVoidOrder() {
    try {
      $this->assertCanVoidOrder();
      return true;
    } catch (Exception $ex) {
      return false;
    }
  }

  public function assertCanCancelOrder() {
    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 '.

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Gate the cancel action on $cart->canCancelOrder() and show a 'not ready yet' state when it returns false.
  2. Let the owning application finish building and activating the cart before offering cancellation.
  3. If carts are stuck in BUILDING, investigate why the application never completed them rather than force-cancelling.

Example fix

// before
$cart->assertCanCancelOrder(); // throws while the cart is still being built

// after
if (!$cart->canCancelOrder()) {
  return $this->newDialog()
    ->setTitle(pht('Unable to Cancel Order'))
    ->appendParagraph(pht('This order can not be cancelled yet.'));
}
// proceed with cancellation
Defensive patterns

Strategy: validation

Validate before calling

if (!$cart->canCancelOrder()) {
  // cart still building or not placed; do not offer cancellation
  return $this->newDialog()->setTitle(pht('Unable to Cancel Order'));
}

Type guard

function isCancellableCart(PhortuneCart $cart) {
  return $cart->canCancelOrder();
}

Try / catch

try {
  $cart->assertCanCancelOrder();
} catch (Exception $ex) {
  // show $ex->getMessage() to the user; statuses BUILDING/READY are expected states
}

Prevention

When it happens

Trigger: Calling assertCanCancelOrder() (or a cancel controller built on it) on a cart whose status is still PhortuneCart::STATUS_BUILDING - typically right after cart creation, before the application has activated it for checkout.

Common situations: Users clicking cancel during the brief building phase of an application-driven order; custom checkout UIs offering cancel too early; orphaned carts left in BUILDING by an application error.

Related errors


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