{"record":{"id":"6cdda6ed46875870","repo":"nautechsystems/nautilus_trader","slug":"durations-seconds-request-parameter-must-contain","errorCode":null,"errorMessage":"`durations_seconds` request parameter must contain non-negative finite values, was {value}","messagePattern":"`durations_seconds` request parameter must contain non-negative finite values, was (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/data/src/engine/time_range.rs","lineNumber":760,"sourceCode":"        .as_array()\n        .context(\"`durations_seconds` request parameter must be an array\")?;\n    values\n        .iter()\n        .map(parse_time_range_duration)\n        .collect::<anyhow::Result<Vec<_>>>()\n}\n\nfn parse_time_range_duration(value: &Value) -> anyhow::Result<Option<DurationNanos>> {\n    if value.is_null() {\n        return Ok(None);\n    }\n\n    let seconds = value.as_f64().with_context(|| {\n        format!(\"`durations_seconds` request parameter must contain numbers or null, was {value}\")\n    })?;\n\n    if !seconds.is_finite() || seconds < 0.0 {\n        anyhow::bail!(\n            \"`durations_seconds` request parameter must contain non-negative finite values, was {value}\"\n        );\n    }\n\n    let nanos = seconds * NANOSECONDS_IN_SECOND as f64;\n    if nanos < 1.0 {\n        anyhow::bail!(\n            \"`durations_seconds` request parameter must contain values of at least one nanosecond, was {value}\"\n        );\n    }\n\n    if nanos > u64::MAX as f64 {\n        anyhow::bail!(\"`durations_seconds` value is too large, was {value}\");\n    }\n\n    Ok(Some(DurationNanos::new(nanos as u64)))\n}\n","sourceCodeStart":742,"sourceCodeEnd":778,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/data/src/engine/time_range.rs#L742-L778","documentation":"parse_time_range_duration parses each element of the `durations_seconds` params array into a DurationNanos. Values must be finite JSON numbers >= 0; NaN/Infinity or negative seconds are rejected. Note null entries are allowed and mean 'no duration'.","triggerScenarios":"Supplying durations_seconds entries of -1, NaN, or +Infinity/-Infinity (serde_json rejects non-finite floats, but Infinity can arise from other producers), or any negative number, in a time-range request's params.","commonSituations":"Config typo with a negative duration; dividing to compute a duration and getting a negative/NaN result; hand-written JSON with invalid numeric literals.","solutions":["Use non-negative finite numbers for every durations_seconds element","Clamp computed durations to >= 0 before building the request","Use null for 'absent duration' entries instead of a sentinel negative number"],"exampleFix":"// before\njson!([\"durations_seconds\" => [-1.0]])\n// after\njson!([\"durations_seconds\" => [0.5, null]])","handlingStrategy":"validation","validationCode":"fn valid_duration(v: &serde_json::Value) -> bool {\n    v.is_null() || matches!(v.as_f64(), Some(s) if s.is_finite() && s >= 0.0)\n}","typeGuard":"let ok = values.iter().all(valid_duration);","tryCatchPattern":null,"preventionTips":["Sanitize computed durations (reject NaN/negative) before building params","Never encode 'absent' with negative sentinels; use JSON null"],"tags":["rust","validation","params","duration"],"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"}