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
- Raise the value being validated so it meets the minimum shown in the message.
- 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.
- 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.
- 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
- Remember the unit split: strings are decimal dollars, getValue() is integer cents — convert before comparing.
- Validate the bound strings themselves with newFromString() once, at config load, so bad bounds fail loudly at deploy time.
- For balances that may legitimately be negative, pass null as the lower bound instead of '0.00 USD'.
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
- Maximum allowed amount is %s.
- Invalid currency format ('%s').
- Unsupported currency '%s'!
- Charge has no transaction ID!
- Stripe charge call did not return an ID!
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/8a0fd295bf761da3.
Report an issue: GitHub.