{"record":{"id":"53693ecdcfdc9963","repo":"nautechsystems/nautilus_trader","slug":"funding-interval-hour-out-of-bounds","errorCode":null,"errorMessage":"funding_interval_hour out of bounds","messagePattern":"funding_interval_hour out of bounds","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/bybit/src/websocket/parse.rs","lineNumber":487,"sourceCode":"        );\n    }\n\n    let funding_rate = funding_rate_str\n        .as_str()\n        .parse::<Decimal>()\n        .with_context(|| {\n            format!(\"invalid funding_rate value '{funding_rate_str}' for {instrument_id}\")\n        })?;\n\n    let funding_interval = if let Some(funding_interval_hour) = &data.funding_interval_hour {\n        let funding_interval_hour = funding_interval_hour\n            .as_str()\n            .parse::<u16>()\n            .context(\"invalid funding_interval_hour value\")?;\n        Some(\n            funding_interval_hour\n                .checked_mul(60)\n                .ok_or_else(|| anyhow::anyhow!(\"funding_interval_hour out of bounds\"))?,\n        )\n    } else {\n        None\n    };\n\n    let next_funding_ns = if let Some(next_funding_time) = &data.next_funding_time {\n        let next_funding_millis = next_funding_time\n            .as_str()\n            .parse::<i64>()\n            .context(\"invalid next_funding_time value\")?;\n        Some(parse_millis_i64(next_funding_millis, \"next_funding_time\")?)\n    } else {\n        None\n    };\n\n    Ok(FundingRateUpdate::new(\n        instrument_id,\n        funding_rate,","sourceCodeStart":469,"sourceCodeEnd":505,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/bybit/src/websocket/parse.rs#L469-L505","documentation":"When converting a Bybit linear ticker's `funding_interval_hour` into minutes, the adapter multiplies hours by 60 with overflow checking. If the multiplication overflows u16 (hours > 1092), the value is out of bounds and this error is thrown.","triggerScenarios":"Receiving a ticker/funding update on a linear instrument where `funding_interval_hour` parses to a u16 value whose *60 exceeds u16 range (>= 1093 hours).","commonSituations":"Upstream schema change or corrupted payload reporting hours in a different unit (e.g. minutes or seconds); fixture data with unrealistic funding intervals.","solutions":["Log the raw funding_interval_hour value and confirm its unit with the current Bybit API docs","Change the parse target to u32/u64 if Bybit widened the field (update the adapter)","Filter or reject tickers with implausible funding intervals before conversion"],"exampleFix":"// before: u16 overflows on large values\nlet funding_interval_hour = data.funding_interval_hour.as_str().parse::<u16>()?;\n// after: widen the type\nlet funding_interval_hour = data.funding_interval_hour.as_str().parse::<u32>()?;","handlingStrategy":"validation","validationCode":"if interval_hour is not None and not (0 < interval_hour < 1093):\n    raise ValueError(f'implausible funding_interval_hour: {interval_hour}')","typeGuard":null,"tryCatchPattern":"match parse_ticker_linear_funding(...) { Err(e) if e.to_string().contains(\"out of bounds\") => { log_payload(raw); skip }, other => other }","preventionTips":["Range-check funding_interval_hour before conversion","Verify the field's unit after Bybit API updates","Add schema tests with realistic funding intervals"],"tags":["rust","bybit","websocket","overflow","funding-rate"],"backgroundTag":"value-out-of-range","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}