{"record":{"id":"e427a54d512ece4b","repo":"nautechsystems/nautilus_trader","slug":"missing-server-timestamp-us-out-in-response","errorCode":null,"errorMessage":"Missing server timestamp (us_out) in response","messagePattern":"Missing server timestamp \\(us_out\\) in response","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/deribit/src/common/parse.rs","lineNumber":154,"sourceCode":"        return false;\n    };\n\n    if seg.is_empty() || seg == \"PERPETUAL\" {\n        return false;\n    }\n    // Combo strategy codes are alphabetic; date segments start with a digit.\n    seg.chars().next().is_some_and(|c| c.is_ascii_alphabetic())\n        && seg.chars().all(|c| c.is_ascii_alphabetic())\n}\n\n/// Extracts server timestamp from response and converts to UnixNanos.\n///\n/// # Errors\n///\n/// Returns an error if the server timestamp (us_out) is missing from the response.\npub fn extract_server_timestamp(us_out: Option<u64>) -> anyhow::Result<UnixNanos> {\n    let us_out =\n        us_out.ok_or_else(|| anyhow::anyhow!(\"Missing server timestamp (us_out) in response\"))?;\n    Ok(UnixNanos::from(us_out * NANOSECONDS_IN_MICROSECOND))\n}\n\n/// Parses a Deribit instrument into a Nautilus [`InstrumentAny`].\n///\n/// Returns `Ok(None)` for unsupported instrument types.\n///\n/// # Errors\n///\n/// Returns an error if:\n/// - Required fields are missing (e.g., strike price for options)\n/// - Timestamp conversion fails\n/// - Decimal conversion fails for fees\npub fn parse_deribit_instrument_any(\n    instrument: &DeribitInstrument,\n    ts_init: UnixNanos,\n    ts_event: UnixNanos,\n) -> anyhow::Result<Option<InstrumentAny>> {","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/deribit/src/common/parse.rs#L136-L172","documentation":"Deribit's account-state and instrument responses include the server clock field us_out, which Nautilus uses as the event/report timestamp (converted from microseconds to UnixNanos). extract_server_timestamp raises this error when us_out is absent (None) from the parsed JSON response, since a valid timestamp is mandatory for the resulting events.","triggerScenarios":"Calling request_account_state, request_instruments/request_instrument, or parsing an account.state response whose JSON lacks the `us_out` field — e.g. an error payload parsed as a success payload, an API change in the response envelope, or a mocked/partial JSON fixture without us_out.","commonSituations":"Deribit API version change removing/renaming us_out in some endpoints; handling error responses (JSON-RPC error) through the success parser; custom test fixtures missing the field.","solutions":["Log/inspect the raw JSON response to confirm whether us_out is present and the response is actually a success result, not a JSON-RPC error.","Handle JSON-RPC error envelopes before calling the parser so error payloads don't reach extract_server_timestamp.","Upgrade the nautilus deribit adapter in case the Deribit API changed the response shape.","Fix test fixtures/mocks to include `us_out` in account.state and instrument responses."],"exampleFix":"// before\nlet parsed = json.as_object().ok_or(...)?;\nlet ts = extract_server_timestamp(parsed[\"result\"][\"us_out\"].as_u64())?;\n\n// after\nif let Some(err) = json[\"error\"].as_object() {\n    return Err(anyhow!(\"Deribit JSON-RPC error: {err:?}\"));\n}\nlet ts = extract_server_timestamp(json[\"result\"][\"us_out\"].as_u64())?;","handlingStrategy":"try-catch","validationCode":"// Rust\nlet us_out = response\n    .get(\"result\")\n    .and_then(|r| r.get(\"us_out\"))\n    .and_then(|v| v.as_u64());\nif us_out.is_none() {\n    // likely a JSON-RPC error envelope; surface it instead\n    anyhow::bail!(\"Deribit response missing us_out: {response}\");\n}","typeGuard":"fn has_server_timestamp(resp: &serde_json::Value) -> bool {\n    resp[\"result\"][\"us_out\"].is_u64()\n}","tryCatchPattern":"match extract_server_timestamp(us_out) {\n    Ok(ts) => ts,\n    Err(e) if e.to_string().contains(\"us_out\") => {\n        log::error!(\"Deribit response missing us_out — check raw payload/API version\");\n        return Err(e);\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Check for JSON-RPC error envelopes before parsing success payloads","Keep the deribit adapter updated against Deribit API changes","Include us_out in all mock fixtures"],"tags":["deribit","rust","websocket","timestamp","response"],"backgroundTag":"unexpected-response-shape","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"}