{"record":{"id":"e99be5f58e94aed8","repo":"nautechsystems/nautilus_trader","slug":"missing-block-number","errorCode":null,"errorMessage":"Missing block number","messagePattern":"Missing block number","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/hypersync/transform.rs","lineNumber":33,"sourceCode":"\nuse alloy::primitives::U256;\nuse hypersync_client::format::Hex;\nuse nautilus_core::{UnixNanos, datetime::NANOSECONDS_IN_SECOND};\nuse nautilus_model::defi::{Block, Blockchain, hex::from_str_hex_to_u64};\nuse ustr::Ustr;\n\n/// Converts a HyperSync block format to our internal [`Block`] type.\n///\n/// # Errors\n///\n/// Returns an error if required block fields are missing or if hex parsing fails.\npub fn transform_hypersync_block(\n    chain: Blockchain,\n    received_block: hypersync_client::simple_types::Block,\n) -> Result<Block, anyhow::Error> {\n    let number = received_block\n        .number\n        .ok_or_else(|| anyhow::anyhow!(\"Missing block number\"))?;\n    let gas_limit = from_str_hex_to_u64(\n        received_block\n            .gas_limit\n            .ok_or_else(|| anyhow::anyhow!(\"Missing gas limit\"))?\n            .encode_hex()\n            .as_str(),\n    )?;\n    let gas_used = from_str_hex_to_u64(\n        received_block\n            .gas_used\n            .ok_or_else(|| anyhow::anyhow!(\"Missing gas used\"))?\n            .encode_hex()\n            .as_str(),\n    )?;\n    let timestamp = from_str_hex_to_u64(\n        received_block\n            .timestamp\n            .ok_or_else(|| anyhow::anyhow!(\"Missing timestamp\"))?","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/hypersync/transform.rs#L15-L51","documentation":"transform_hypersync_block converts a hypersync_client Block into the domain Block. The error fires when the source block's number field is None — a block without a number cannot be mapped into the domain model, which keys blocks by height.","triggerScenarios":"pool_events_from_response receives a HyperSync response whose block object has number == None and passes it to transform_hypersync_block.","commonSituations":"Partial or malformed HyperSync responses; upstream API/schema changes; synthetic test blocks lacking a number; version mismatch between hypersync-client and expected schema.","solutions":["Verify the HyperSync request selects the block number field","Skip blocks with number == None and re-fetch them","Check/update hypersync-client version for schema regressions","Log the raw response to diagnose upstream data gaps"],"exampleFix":"// before\nlet number = received_block.number.ok_or_else(|| anyhow::anyhow!(\"Missing block number\"))?;\n// after\nlet Some(number) = received_block.number else {\n    tracing::warn!(\"hypersync block missing number; skipping block\");\n    return Ok(None);\n};","handlingStrategy":"validation","validationCode":"if received_block.number.is_none() {\n    tracing::warn!(\"skipping hypersync block without number\");\n    return Ok(None);\n}","typeGuard":"fn block_has_number(b: &hypersync_client::simple_types::Block) -> bool {\n    b.number.is_some()\n}","tryCatchPattern":"match transform_hypersync_block(chain, block) {\n    Ok(b) => /* use b */,\n    Err(e) => { tracing::warn!(\"block transform failed: {e}\"); continue; }\n}","preventionTips":["Include the block number in HyperSync block field selection","Treat Option fields as required at the transform boundary and skip incomplete blocks","Keep hypersync-client versions pinned and tested"],"tags":["hypersync","blockchain","blocks","missing-field"],"backgroundTag":"missing-required-argument","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"}