nautechsystems/nautilus_trader · error
Invalid funding_rate value: {e}
Error message
Invalid funding_rate value: {e} What it means
parse_funding_rate_msg converts an OKX funding-rate channel message into a FundingRateUpdate. The funding_rate field is a string that must parse as a Decimal; if OKX sends a malformed, empty, or unexpectedly formatted value, the parse fails and this error is raised wrapping the Decimal parse error.
Source
Thrown at crates/adapters/okx/src/common/parse.rs:561
))
}
/// Parses an [`OKXFundingRateMsg`] into a [`FundingRateUpdate`].
///
/// # Errors
///
/// Returns an error if the `funding_rate` field fails
/// to parse into a Decimal value or `next_funding_time` fails to parse into a positive, in bounds interval.
pub fn parse_funding_rate_msg(
msg: &OKXFundingRateMsg,
instrument_id: InstrumentId,
ts_init: UnixNanos,
) -> anyhow::Result<FundingRateUpdate> {
let funding_rate = msg
.funding_rate
.as_str()
.parse::<Decimal>()
.map_err(|e| anyhow::anyhow!("Invalid funding_rate value: {e}"))?;
let funding_time = parse_millisecond_timestamp(msg.funding_time);
let next_funding_time = parse_millisecond_timestamp(msg.next_funding_time);
let funding_interval_nanos =
next_funding_time
.duration_since(&funding_time)
.ok_or(anyhow::anyhow!(
"Invalid funding_interval, cannot be negative"
))?;
let funding_interval = u16::try_from(funding_interval_nanos.as_mins())
.context("funding_interval out of bounds")?;
let ts_event = parse_millisecond_timestamp(msg.ts);
Ok(FundingRateUpdate::new(
instrument_id,
funding_rate,
Some(funding_interval),
Some(funding_time),View on GitHub (pinned to 18893faf8b)
Solutions
- Log msg.funding_rate and the full raw message when this fires to see the actual malformed value.
- Handle empty/placeholder values by skipping the update (return Ok with early exit) rather than erroring the whole message batch.
- Pre-sanitize: trim the string and reject empty before parse::<Decimal>(); consider accepting scientific notation via Decimal::from_scientific as a fallback.
- Check the adapter version against the current OKX funding-rate channel schema in case the field format changed.
Example fix
// before
let funding_rate = msg
.funding_rate
.as_str()
.parse::<Decimal>()
.map_err(|e| anyhow::anyhow!("Invalid funding_rate value: {e}"))?;
// after
let raw = msg.funding_rate.as_str().trim();
if raw.is_empty() {
anyhow::bail!("skipping funding rate update: empty funding_rate");
}
let funding_rate = raw.parse::<Decimal>()
.map_err(|e| anyhow::anyhow!("Invalid funding_rate value: {e}"))?; Defensive patterns
Strategy: validation
Validate before calling
fn parse_okx_decimal(s: &str) -> Option<Decimal> {
let s = s.trim();
if s.is_empty() { return None; }
s.parse::<Decimal>().ok()
} Try / catch
match parse_funding_rate_msg(&msg, ts_init) {
Ok(u) => emit(u),
Err(e) => log::warn!("dropping funding rate update: {e}"),
} Prevention
- Trim and emptiness-check string numeric fields before Decimal parsing.
- Treat funding-rate snapshots with placeholder values as skippable updates.
- Log raw messages from the funding-rate channel so malformed payloads are quickly diagnosable.
When it happens
Trigger: A funding-rate websocket message (parsed via parse_funding_rate_msg or parse_funding_rate_msg_vec) carries a funding_rate string that is empty, non-numeric, or uses a format Decimal cannot parse (e.g. scientific notation edge cases or locale-formatted numbers).
Common situations: OKX sends an initial/placeholder snapshot with an empty fundingRate before the first computed value; API change in the funding-rate channel payload; intercepting messages from the wrong channel so unrelated strings land in the funding_rate field; proxy/CDN mangling the payload.
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
- Invalid funding_interval, cannot be negative
- Unsupported Deribit resolution: {resolution}
- Unknown order direction: {}
- Unknown trade direction: {}
- Unknown position currency '{pos_ccy}' for instrument {instru
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/fded485b605292ce.
Report an issue: GitHub.