{"record":{"id":"a42ca7d55fd86d44","repo":"nautechsystems/nautilus_trader","slug":"missing-data-in-setfeeprotocol-event-log","errorCode":null,"errorMessage":"Missing data in SetFeeProtocol event log","messagePattern":"Missing data in SetFeeProtocol event log","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/exchanges/parsing/pancakeswap_v3/fee_protocol_update.rs","lineNumber":94,"sourceCode":"            log.address\n                .clone()\n                .expect(\"Contract address should be set in logs\")\n                .as_ref(),\n        );\n        let pool_identifier = PoolIdentifier::Address(Ustr::from(&pool_address.to_string()));\n\n        Ok(FeeProtocolUpdateEvent::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            decoded.fee_protocol0_new,\n            decoded.fee_protocol1_new,\n        ))\n    } else {\n        anyhow::bail!(\"Missing data in SetFeeProtocol event log\");\n    }\n}\n\n/// Parses a PancakeSwap V3 `SetFeeProtocol` 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_fee_protocol_update_event_rpc(\n    dex: SharedDex,\n    log: &RpcLog,\n) -> anyhow::Result<FeeProtocolUpdateEvent> {\n    rpc_log::validate_event_signature(\n        log,\n        FEE_PROTOCOL_UPDATE_EVENT_SIGNATURE_HASH,\n        \"SetFeeProtocol\",\n    )?;\n","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/exchanges/parsing/pancakeswap_v3/fee_protocol_update.rs#L76-L112","documentation":"In the Hypersync parse path, `log.data` is an `Option`; if it is `None` the parser has nothing to decode and bails with this message. Hypersync logs normally carry data for SetFeeProtocol events, so a missing data field indicates the log was fetched incompletely or is not the expected event.","triggerScenarios":"Calling `parse_fee_protocol_update_event_hypersync` with a log where `log.data == None` — e.g. a Hypersync query that omitted the data column, a log matched by a topic filter but lacking a data payload, or an anonymous/sparse event from a non-standard contract.","commonSituations":"A misconfigured Hypersync field selection that drops the data column; manually constructed test logs without data; replaying logs from an exporter that strips empty payloads.","solutions":["Ensure the Hypersync query requests the full log object including the data field.","Treat data-less logs as ignorable: match on `Some(data)` and skip `None` cases with a debug log instead of erroring if your pipeline tolerates gaps.","Filter strictly on the SetFeeProtocol topic0 so only events guaranteed to carry data are parsed.","Verify the emitting contract's SetFeeProtocol event actually has non-indexed parameters (non-empty data)."],"exampleFix":"// before\n} else {\n    anyhow::bail!(\"Missing data in SetFeeProtocol event log\");\n}\n// after\n} else {\n    tracing::debug!(\"SetFeeProtocol log {} has no data; skipping\", log.transaction_hash);\n    return Ok(None);\n}","handlingStrategy":"validation","validationCode":"// ensure the hypersync query selects full logs (including data), then guard:\nif log.data.is_none() {\n    tracing::debug!(\"SetFeeProtocol log without data; skipping\");\n    return Ok(None);\n}","typeGuard":"fn has_event_data(log: &HyperSyncLog) -> bool {\n    log.data.as_ref().map(|d| !d.as_ref().is_empty()).unwrap_or(false)\n}","tryCatchPattern":"match parse_fee_protocol_update_event_hypersync(dex, &log) {\n    Ok(ev) => store(ev),\n    Err(e) if e.to_string().contains(\"Missing data\") => {\n        tracing::debug!(\"log had no data; ignoring\");\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Configure the Hypersync query to return the complete log object (data field included).","Filter on topic0 so only SetFeeProtocol events (which always carry data) reach the parser.","Use Option matching (if let Some(data)) in the parser to make the None case explicit.","Test the pipeline with real fetched logs, not only hand-built fixtures."],"tags":["rust","anyhow","event-parsing","pancakeswap-v3","missing-data","hypersync"],"backgroundTag":"empty-required-field","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"}