{"record":{"id":"371a4c885c040a3b","repo":"nautechsystems/nautilus_trader","slug":"invalid-fee-protocol1-new-e","errorCode":null,"errorMessage":"Invalid fee_protocol1_new '{}': {e}","messagePattern":"Invalid fee_protocol1_new '(.+?)': (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/cache/database.rs","lineNumber":1906,"sourceCode":"        let mut fee_protocol1s: Vec<i32> = Vec::with_capacity(len);\n\n        // Fill vectors from updates\n        for update in updates {\n            chain_ids.push(chain_id as i32);\n            dex_names.push(update.dex.name.to_string());\n            pool_identifiers.push(update.pool_identifier.to_string());\n            blocks.push(update.block as i64);\n            transaction_hashes.push(update.transaction_hash.clone());\n            transaction_indices.push(update.transaction_index as i32);\n            log_indices.push(update.log_index as i32);\n            fee_protocol0s.push(i32::try_from(update.fee_protocol0_new).map_err(|e| {\n                anyhow::anyhow!(\n                    \"Invalid fee_protocol0_new '{}': {e}\",\n                    update.fee_protocol0_new\n                )\n            })?);\n            fee_protocol1s.push(i32::try_from(update.fee_protocol1_new).map_err(|e| {\n                anyhow::anyhow!(\n                    \"Invalid fee_protocol1_new '{}': {e}\",\n                    update.fee_protocol1_new\n                )\n            })?);\n        }\n\n        // Execute batch insert with UNNEST\n        sqlx::query(\n            \"\n            INSERT INTO pool_fee_protocol_update_event (\n                chain_id, dex_name, pool_identifier, block, transaction_hash, transaction_index,\n                log_index, fee_protocol0_new, fee_protocol1_new\n            )\n            SELECT\n                chain_id, dex_name, pool_identifier, block, transaction_hash, transaction_index,\n                log_index, fee_protocol0_new, fee_protocol1_new\n            FROM UNNEST(\n                $1::INT[], $2::TEXT[], $3::TEXT[], $4::INT[], $5::TEXT[], $6::INT[],","sourceCodeStart":1888,"sourceCodeEnd":1924,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/cache/database.rs#L1888-L1924","documentation":"Same conversion failure as its sibling error, but for `fee_protocol1_new` (token1's new fee-protocol value): `i32::try_from` rejects the value because it does not fit in i32. The raw value is included in the message for diagnosis. The fee-protocol-update batch insert aborts before SQL execution.","triggerScenarios":"A `FeeProtocolUpdate` whose `fee_protocol1_new` (u64/usize) exceeds i32::MAX or is below i32::MIN is passed to the batch insert of pool fee-protocol update events.","commonSituations":"Corrupt or misparsed on-chain data; sentinel values (e.g. u64::MAX) from a decoder bug; ABI layout drift between contract versions changing where fee_protocol1 is read from.","solutions":["Inspect the logged `fee_protocol1_new` value and trace its decoding origin","Validate the value fits the fee-protocol domain (0..=255) before inserting","Fix the event decoder/ABI offset for fee_protocol1_new if the value is systematically wrong","Reject or skip malformed events upstream rather than failing the batch"],"exampleFix":"// before\nfee_protocol1s.push(i32::try_from(update.fee_protocol1_new).map_err(|e| {\n    anyhow::anyhow!(\"Invalid fee_protocol1_new '{}': {e}\", update.fee_protocol1_new)\n})?);\n// after: domain-range validation before conversion\nif update.fee_protocol1_new > 255 {\n    anyhow::bail!(\"fee_protocol1_new {} outside valid fee-protocol range\", update.fee_protocol1_new);\n}\nfee_protocol1s.push(i32::try_from(update.fee_protocol1_new)?);","handlingStrategy":"validation","validationCode":"fn validate_fee_protocol1(v: u64) -> anyhow::Result<()> {\n    anyhow::ensure!(v <= 255, \"fee_protocol1_new {v} outside fee-protocol range 0..=255\");\n    Ok(())\n}","typeGuard":"fn fits_i32(v: u64) -> bool { v <= i32::MAX as u64 }","tryCatchPattern":"if let Err(e) = validate_fee_protocol1(update.fee_protocol1_new) {\n    tracing::error!(\"dropping fee-protocol update: {e}\");\n    return Ok(()); // or skip this update\n}","preventionTips":["Use narrow types (u8) for fee-protocol values at decode time","Check ABI offsets when upgrading contract bindings","Reject sentinel values (u64::MAX) upstream","Test decoders against known-good on-chain events"],"tags":["integer-overflow","type-conversion","validation"],"backgroundTag":"value-out-of-range","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"}