nautechsystems/nautilus_trader · error
Quote spend limit `max_amount` '{max_amount}' must be a base
Error message
Quote spend limit `max_amount` '{max_amount}' must be a base-10 unsigned integer string What it means
A quote spend limit's max_amount must be a non-empty base-10 unsigned integer string (no decimals, signs, or hex), because it is parsed as an on-chain U256 raw amount in the token's smallest unit. The library throws this when the string is empty or contains any non-digit bytes, or when U256::from_str overflows.
Source
Thrown at crates/adapters/blockchain/src/execution/client.rs:311
let token_out = validate_address(limit.token_out.as_str())?;
let spend_token = validate_address(limit.spend_token.as_str())?;
if !parsed_pairs.contains(&(token_in, token_out)) {
anyhow::bail!(
"Quote spend limit pair {token_in} -> {token_out} is not in the `allowed_token_pairs` allowlist"
);
}
if spend_token != token_in {
anyhow::bail!(
"Quote spend limit for {token_in} -> {token_out} is denominated in {spend_token}; `spend_token` must match `token_in`"
);
}
if limit.max_amount.is_empty()
|| !limit.max_amount.bytes().all(|byte| byte.is_ascii_digit())
{
anyhow::bail!(
"Quote spend limit `max_amount` '{}' must be a base-10 unsigned integer string",
limit.max_amount
);
}
let max_amount = U256::from_str(&limit.max_amount).map_err(|_| {
anyhow::anyhow!(
"Quote spend limit `max_amount` '{}' exceeds the U256 range",
limit.max_amount
)
})?;
let ceiling = QuoteSpendCeiling {
spend_token,
spend_token_decimals: limit.spend_token_decimals,
max_amount,
};
if parsed_quote_spend_limits
.insert((token_in, token_out), ceiling)View on GitHub (pinned to 18893faf8b)
Solutions
- Provide max_amount as a decimal integer string of the raw token amount (smallest unit)
- Convert decimal/float amounts to integer base units before writing config (multiply by token decimals)
- Remove any 0x prefix, sign, decimal point, or exponent characters
Example fix
// before max_amount = "1.5" // after max_amount = "1500000000000000000"
Defensive patterns
Strategy: validation
Validate before calling
fn parse_max_amount(s: &str) -> Result<U256, String> {
if s.is_empty() || !s.bytes().all(|b| b.is_ascii_digit()) {
return Err(format!("max_amount '{s}' must be a base-10 unsigned integer string"));
}
U256::from_str(s).map_err(|e| format!("max_amount '{s}' not representable as U256: {e}"))
} Prevention
- Store amounts as integer strings in the token's smallest unit, never floats or decimals
- Provide a CLI/helper to convert human amounts to wei
- Document the format next to the config field
When it happens
Trigger: Calling new/transaction_limits with config.quote_spend_limits entries whose max_amount is "", contains '.', '-', 'e', hex chars, whitespace, or exceeds U256::MAX.
Common situations: Writing a decimal human amount like "1.5" instead of wei-integer "1500000000000000000"; using scientific notation "1e18"; empty value left by a template; pasting a 0x-prefixed hex amount.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- config_path must be in format 'module.path:ClassName', was {
- {field} must be in format 'module.path:ClassName'
- config_path must be in format 'module.path:ClassName', was {
- Quote spend limit `max_amount` '{}' exceeds the U256 range
- Invalid config type for AxExecutionClientFactory. Expected A
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/0275b9933b4ff455.
Report an issue: GitHub.