nautechsystems/nautilus_trader · error
raw wei value exceeds 128-bit range
Error message
raw wei value exceeds 128-bit range
What it means
Money::from_wei accepts a raw wei value as U256 but the internal fixed-precision representation only stores values up to i128. The U256-to-u128 TryInto conversion is unwrapped with expect, so any wei amount larger than u128::MAX panics with this message (a follow-up assert also rejects values above i128::MAX). The library throws it because amounts exceeding the native integer width cannot be represented losslessly in Money.
Source
Thrown at crates/model/src/defi/types/money.rs:62
/// # Panics
///
/// Panics if `currency.precision` is not 18, or if the raw wei value exceeds the
/// signed 128-bit range.
pub fn from_wei<U>(raw_wei: U, currency: Currency) -> Self
where
U: Into<U256>,
{
assert!(
currency.precision == 18,
"`from_wei` requires a currency with precision 18, was {} for {}",
currency.precision,
currency.code,
);
let raw_u256: U256 = raw_wei.into();
let raw_u128: u128 = raw_u256
.try_into()
.expect("raw wei value exceeds 128-bit range");
assert!(
raw_u128 <= i128::MAX as u128,
"raw wei value exceeds signed 128-bit range"
);
let raw_i128: i128 = raw_u128 as i128;
Self::from_raw(raw_i128, currency)
}
/// Converts this [`Money`] instance to raw wei value.
///
/// # Panics
///
/// Panics if `self.currency.precision` is not 18 or `self.raw` is negative.
/// For other precisions convert to precision 18 first.
#[must_use]
pub fn to_wei(&self) -> U256 {View on GitHub (pinned to 18893faf8b)
Solutions
- Check the raw value before conversion: only call from_wei when raw_wei <= U256::from(u128::MAX) (and <= i128::MAX if sign matters).
- Reject or clamp the value at the data-ingestion layer; skip the token/instrument or log a warning instead of converting.
- Verify the ABI/log decoding that produced the U256 — a decode bug can yield spuriously large values.
- If such magnitudes are legitimate, request upstream support for a big-number (U256) representation instead of working around it.
Example fix
// before
let money = Money::from_wei(raw_wei_u256, currency); // panics if raw > u128::MAX
// after
let money = if raw_wei_u256 <= U256::from(u128::MAX) {
Money::from_wei(raw_wei_u256, currency)
} else {
return Err("wei amount exceeds 128-bit range".to_string());
}; Defensive patterns
Strategy: validation
Validate before calling
use alloy_primitives::U256;
fn wei_fits_u128(raw_wei: U256) -> bool {
raw_wei <= U256::from(i128::MAX)
} Type guard
fn fits_i128(raw: U256) -> Option<u128> {
let r: u128 = raw.try_into().ok()?;
(r <= i128::MAX as u128).then_some(r)
} Prevention
- Range-check raw wei against u128/i128 bounds before any from_wei conversion.
- Sanity-check token supplies and decoded amounts at ingestion time.
- Watch for double-scaling of wei values in adapter code.
When it happens
Trigger: Calling Money::from_wei (or its Python/FFI wrapper money_from_wei) with a raw wei value > u128::MAX (≈3.4e38), e.g. huge token supplies or overflowed aggregation results, or passing a negative/wrapped U256 produced by a downstream ABI decode bug.
Common situations: Indexing a token with an enormous total supply (or high decimals) whose raw wei amounts overflow 128 bits; feeding raw on-chain values from a mis-decoded log; upgrading a data pipeline to aggregate balances across many wallets so the sum overflows.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- raw wei value exceeds 128-bit range
- raw wei value exceeds unsigned 128-bit range
- DurationNanos overflow in from_micros
- {e}
- Native currency not specified for chain {}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/4fb0f6ef1bc41748.
Report an issue: GitHub.