{"record":{"id":"b1399fae436388d3","repo":"nautechsystems/nautilus_trader","slug":"missing-data-in-collect-event-log","errorCode":null,"errorMessage":"Missing data in collect event log","messagePattern":"Missing data in collect event log","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/exchanges/parsing/uniswap_v3/collect.rs","lineNumber":117,"sourceCode":"                .as_ref(),\n        );\n        let pool_identifier = PoolIdentifier::Address(Ustr::from(&pool_address.to_string()));\n        Ok(CollectEvent::new(\n            dex,\n            pool_identifier,\n            extract_block_number(log)?,\n            extract_transaction_hash(log)?,\n            extract_transaction_index(log)?,\n            extract_log_index(log)?,\n            owner,\n            decoded.recipient,\n            tick_lower,\n            tick_upper,\n            decoded.amount0,\n            decoded.amount1,\n        ))\n    } else {\n        Err(anyhow::anyhow!(\"Missing data in collect event log\"))\n    }\n}\n\n/// Parses a collect event from an RPC log.\n///\n/// # Errors\n///\n/// Returns an error if the log parsing fails or if the event data is invalid.\npub fn parse_collect_event_rpc(dex: SharedDex, log: &RpcLog) -> anyhow::Result<CollectEvent> {\n    rpc_log::validate_event_signature(log, COLLECT_EVENT_SIGNATURE_HASH, \"Collect\")?;\n\n    let owner = rpc_log::extract_address_from_topic(log, 1, \"owner\")?;\n\n    // Extract int24 tickLower from topic2 (stored as a 32-byte padded value)\n    let tick_lower_bytes = rpc_log::extract_topic_bytes(log, 2)?;\n    let tick_lower = i32::from_be_bytes(tick_lower_bytes[28..32].try_into()?);\n\n    // Extract int24 tickUpper from topic3 (stored as a 32-byte padded value)","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/exchanges/parsing/uniswap_v3/collect.rs#L99-L135","documentation":"parse_collect_event_hypersync throws this when the Hypersync-decoded Collect event payload is None, so amount0/amount1 and position tick data cannot be assembled into a Collect event. The parser refuses to emit a collect event with missing monetary amounts because those are required domain values. It mirrors the guard pattern used by the other uniswap_v3 event parsers.","triggerScenarios":"Calling parse_collect_event_hypersync with a log whose decoded field is None — topic0 matched the Collect signature but the data section was missing/truncated or Hypersync could not decode it into the expected Collect struct.","commonSituations":"Indexing NonfungiblePositionManager logs where an ABI update changed the expected Collect layout; non-standard fork contracts emitting Collect-like topic0 with no data; partially indexed blocks from Hypersync during reorgs; stale test fixtures.","solutions":["Confirm the source contract is the canonical Uniswap V3 NonfungiblePositionManager and the log data section is present and correctly sized.","Re-check the Hypersync event/ABI registration for Collect so decoding yields Some(decoded).","Filter out logs with empty data before calling the parser, logging them for investigation instead of failing the batch.","Align adapter and Hypersync client versions, then re-fetch the affected block range."],"exampleFix":"// before\nlet event = parse_collect_event_hypersync(&log)?;\n// after\nif log.data.is_empty() {\n    tracing::warn!(tx = ?log.transaction_hash, \"collect log has no data; skipping\");\n    return Ok(None);\n}\nlet event = parse_collect_event_hypersync(&log)?;","handlingStrategy":"validation","validationCode":"fn can_parse_collect(log: &Log) -> bool {\n    log.data.len() >= 64 // amount0, amount1 words\n}","typeGuard":"fn has_decoded_collect(decoded: &Option<CollectDecoded>) -> bool {\n    decoded.is_some()\n}","tryCatchPattern":"match parse_collect_event_hypersync(&log) {\n    Ok(event) => handle(event),\n    Err(e) if e.to_string().contains(\"Missing data in collect event log\") => {\n        tracing::warn!(\"skipping malformed collect log\");\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Verify logs come from the canonical NonfungiblePositionManager.","Filter empty-data logs before parsing.","Re-sync ranges after Hypersync ABI or client updates.","Track skipped events in metrics to detect ABI drift early."],"tags":["blockchain","uniswap-v3","log-parsing","hypersync"],"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"}