{"record":{"id":"2ed76a5647482da9","repo":"nautechsystems/nautilus_trader","slug":"the-block-doesn-t-contain-a-header","errorCode":null,"errorMessage":"The block doesn't contain a header","messagePattern":"The block doesn't contain a header","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/dydx/src/grpc/client.rs","lineNumber":400,"sourceCode":"            .base\n            .get_latest_block(req)\n            .await?\n            .into_inner()\n            .sdk_block\n            .ok_or_else(|| anyhow::anyhow!(\"The latest block is empty\"))?;\n        Ok(latest_block)\n    }\n\n    /// Query for the latest block height.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if the query fails.\n    pub async fn latest_block_height(&mut self) -> Result<Height, anyhow::Error> {\n        let latest_block = self.latest_block().await?;\n        let header = latest_block\n            .header\n            .ok_or_else(|| anyhow::anyhow!(\"The block doesn't contain a header\"))?;\n        let height = Height(header.height.try_into()?);\n        Ok(height)\n    }\n\n    /// Query for all perpetual markets.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if the query fails.\n    pub async fn get_perpetuals(&mut self) -> Result<Vec<Perpetual>, anyhow::Error> {\n        let req = QueryAllPerpetualsRequest { pagination: None };\n        let response = self.perpetuals.all_perpetuals(req).await?.into_inner();\n        Ok(response.perpetual)\n    }\n\n    /// Query for all CLOB pairs.\n    ///\n    /// # Errors","sourceCodeStart":382,"sourceCodeEnd":418,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/dydx/src/grpc/client.rs#L382-L418","documentation":"latest_block_height extracts the header from the latest block response to read its height; if the block carries no header the library cannot derive a Height and raises this error. The header is required metadata on any well-formed Tendermint/CometBFT block, so this signals a malformed or mis-decoded response.","triggerScenarios":"Calling latest_block_height when latest_block returned a block whose `header` field is None — proto decode mismatch or a degraded node response.","commonSituations":"Same endpoint/version issues as the empty-block error: stale or syncing node, incompatible proto definitions where the header lands in a different oneof variant.","solutions":["Retry against the same node; transient decode issues may clear after sync.","Use a different, healthy gRPC endpoint.","Align tendermint/comet proto crate versions with the node's CometBFT release so Header decodes into the expected field.","Log the raw GetLatestBlock response to confirm whether header is absent server-side or lost in decoding."],"exampleFix":"// before\nlet height = client.latest_block_height().await?;\n// after: fall back to an alternate source\nlet height = match client.latest_block_height().await {\n    Ok(h) => h,\n    Err(e) if e.to_string().contains(\"doesn't contain a header\") => {\n        let h = grpc_status_client.latest_block_height().await?;\n        h\n    }\n    Err(e) => return Err(e),\n};","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"let height = client.latest_block_height().await\n    .or_else(|_| fallback_client.latest_block_height().await)?;","preventionTips":["Maintain a secondary RPC endpoint for block queries","Retry once before failing the whole operation","Monitor node health/sync status of configured endpoints"],"tags":["grpc","cosmos","block","header"],"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-14T05:17:10.506Z"}