phacility/phabricator · error · Exception

Minimum allowed amount is %s.

Error message

Minimum allowed amount is %s.

What it means

Thrown by PhortuneCurrency::assertInRange($minimum, $maximum) when the object's value (stored internally as integer cents) is strictly below the parsed $minimum. assertInRange is Phortune's bounds-check API: both bounds are currency strings parsed with newFromString(), null skips a check, and the bounds are inclusive. The message reports the minimum formatted for display (e.g. '$5.00 USD') so the caller can surface it directly to a user.

Source

Thrown at src/applications/phortune/currency/PhortuneCurrency.php:218

   * @return this
   */
  public function assertInRange($minimum, $maximum) {
    if ($minimum !== null && $maximum !== null) {
      $min = self::newFromString($minimum);
      $max = self::newFromString($maximum);
      if ($min->value > $max->value) {
        throw new Exception(
          pht(
            'Range (%s - %s) is not valid!',
            $min->formatForDisplay(),
            $max->formatForDisplay()));
      }
    }

    if ($minimum !== null) {
      $min = self::newFromString($minimum);
      if ($min->value > $this->value) {
        throw new Exception(
          pht(
            'Minimum allowed amount is %s.',
            $min->formatForDisplay()));
      }
    }

    if ($maximum !== null) {
      $max = self::newFromString($maximum);
      if ($max->value < $this->value) {
        throw new Exception(
          pht(
            'Maximum allowed amount is %s.',
            $max->formatForDisplay()));
      }
    }

    return $this;
  }

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Raise the value being validated so it meets the minimum shown in the message.
  2. Re-check that the minimum string itself is what you intended — a '5' meaning 5 cents vs '$5.00' meaning 500 cents mixup is the most common cause.
  3. If negative amounts (account credit/debt) are legitimate, pass null as the minimum or use a negative bound; assertInRange exists precisely because zero-checks alone are wrong for signed balances.
  4. Wrap the call in try/catch Exception and convert the message into a form-field validation error instead of a 500.

Example fix

// before
$price->assertInRange('5.00 USD', '500.00 USD');

// after
try {
  $price->assertInRange('5.00 USD', '500.00 USD');
} catch (Exception $ex) {
  $e = new PhabricatorApplicationTransactionValidationError(
    PhortuneProductTransaction::TRANSACTIONTYPE,
    pht('Invalid'),
    $ex->getMessage(),
    null);
  throw new PhabricatorApplicationTransactionValidationException(array($e));
}
Defensive patterns

Strategy: validation

Validate before calling

// Compare in cents BEFORE calling assertInRange.
function currency_meets_minimum(PhortuneCurrency $amount, $minimum_string) {
  if ($minimum_string === null) {
    return true;
  }
  $min = PhortuneCurrency::newFromString($minimum_string);
  return $amount->getValue() >= $min->getValue();
}

if (!currency_meets_minimum($price, $minimum)) {
  $field_error = pht(
    'Minimum allowed amount is %s.',
    PhortuneCurrency::newFromString($minimum)->formatForDisplay());
}

Try / catch

try {
  $price->assertInRange($minimum, $maximum);
} catch (Exception $ex) {
  // Message already carries the violated bound, e.g. 'Minimum allowed amount is $5.00 USD.'
  throw new PhabricatorApplicationTransactionValidationException(
    array(
      new PhabricatorApplicationTransactionValidationError(
        $transaction_type,
        pht('Invalid'),
        $ex->getMessage(),
        null),
    ));
}

Prevention

When it happens

Trigger: Calling e.g. PhortuneCurrency::newFromString('1.00 USD')->assertInRange('5.00 USD', null) — 100 cents < 500 cents throws. Also assertInRange('5.00 USD', '10.00 USD') on a $1.00 product price, or a range check on a cart total that falls under a provider's minimum charge.

Common situations: Product/subscription pricing forms with a minimum purchase floor; enforcing a payment gateway's minimum transaction size; validating a refund or credit amount that legitimately went negative while the minimum assumed non-negative; unit fixtures that forget the bound strings are decimal dollars while stored values are cents.

Related errors


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