nautechsystems/nautilus_trader · error · anyhow::Error
Gamma {scope} filter '{key}' must be a decimal number: {e}
Error message
Gamma {scope} filter '{key}' must be a decimal number: {e} What it means
parse_gamma_filter_decimal parses a Gamma filter as a Decimal via parse_decimal_exact and re-wraps failures as 'Gamma {scope} filter {key} must be a decimal number'. parse_decimal_exact requires exact decimal representation, so scientific notation or extra precision that cannot be represented exactly will fail.
Source
Thrown at crates/adapters/polymarket/src/providers.rs:993
anyhow::bail!("Gamma {scope} filter '{key}' must be true or false, was '{value}'")
}
}
fn parse_gamma_filter_u32(scope: &str, key: &str, value: &str) -> anyhow::Result<u32> {
value.parse::<u32>().map_err(|e| {
anyhow::anyhow!("Gamma {scope} filter '{key}' must be an unsigned integer: {e}")
})
}
fn parse_gamma_filter_u64(scope: &str, key: &str, value: &str) -> anyhow::Result<u64> {
value.parse::<u64>().map_err(|e| {
anyhow::anyhow!("Gamma {scope} filter '{key}' must be an unsigned integer: {e}")
})
}
fn parse_gamma_filter_decimal(scope: &str, key: &str, value: &str) -> anyhow::Result<Decimal> {
parse_decimal_exact(value)
.map_err(|e| anyhow::anyhow!("Gamma {scope} filter '{key}' must be a decimal number: {e}"))
}
fn parse_gamma_filter_list(scope: &str, key: &str, value: &str) -> anyhow::Result<Vec<String>> {
let values = value
.split(',')
.map(str::trim)
.map(str::to_string)
.collect::<Vec<_>>();
if values.is_empty() || values.iter().any(String::is_empty) {
anyhow::bail!("Gamma {scope} filter '{key}' must contain non-empty comma-separated values")
}
Ok(values)
}
fn parse_gamma_numeric_filter_list(
scope: &str,
key: &str,View on GitHub (pinned to 18893faf8b)
Solutions
- Write the value as a plain decimal string with a dot separator, e.g. "0.00001" instead of "1e-5"
- Convert commas to dots and remove currency symbols/thousands separators before parsing
- Round the value to the exchange's supported precision before passing it
- Call parse_decimal_exact on the value in your own code first to get the raw reason
Example fix
// before
filters.insert("min_liquidity", "1e5");
// after
filters.insert("min_liquidity", "100000"); Defensive patterns
Strategy: validation
Validate before calling
// Rust: plain decimal check mirroring parse_decimal_exact expectations
fn is_plain_decimal(v: &str) -> bool {
let v = v.trim();
!v.is_empty() && !v.contains('e') && !v.contains('E')
&& v.replace('.', "").chars().all(|c| c.is_ascii_digit())
&& v.matches('.').count() <= 1
} Prevention
- Avoid scientific notation in decimal config values; write 0.00001 not 1e-5
- Normalize locale decimal commas to dots before parsing
- Round to the venue's tick size before passing thresholds
When it happens
Trigger: Supplying a price/threshold-style Gamma filter like "1e-5", "0.1.2", "", or a value with too many decimal places that parse_decimal_exact rejects.
Common situations: Scientific-notation numbers from JSON configs, locale decimal commas ("1,25"), or over-precise floats from upstream systems.
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
- Gamma {scope} filter '{key}' must be an unsigned integer: {e
- Polymarket market BUY amount {} pUSD truncates to zero at {L
- invalid signed E18 integer for {field}: {value}
- fee exponent must be non-negative
- Failed to parse tick size '{new_tick_size}': {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/c596a911c949786b.
Report an issue: GitHub.