{"record":{"id":"4b7b0b1676d761a3","repo":"nautechsystems/nautilus_trader","slug":"restored-pool-instrument-id-has-no-fee","errorCode":null,"errorMessage":"Restored pool {instrument_id} has no fee","messagePattern":"Restored pool (.+?) has no fee","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/execution/client.rs","lineNumber":1082,"sourceCode":"            intent\n                .pool_address\n                .as_deref()\n                .ok_or_else(|| anyhow::anyhow!(\"Persisted swap intent has no pool address\"))?,\n        )?;\n        anyhow::ensure!(\n            pool.address == pool_address,\n            \"Persisted pool {pool_address} does not match restored pool {}\",\n            pool.address\n        );\n        let amount_in = U256::from_str(\n            intent\n                .amount_in\n                .as_deref()\n                .ok_or_else(|| anyhow::anyhow!(\"Persisted swap intent has no input amount\"))?,\n        )?;\n        let fee = U24::try_from(\n            pool.fee\n                .ok_or_else(|| anyhow::anyhow!(\"Restored pool {instrument_id} has no fee\"))?,\n        )?;\n        let quote_token = pool.get_quote_token();\n        let quote_currency = Currency::new_checked(\n            &quote_token.symbol,\n            quote_token.decimals,\n            0,\n            &quote_token.name,\n            CurrencyType::Crypto,\n        )?;\n        let (token_in, token_out) = swap_token_pair(\n            order.order_side(),\n            pool.get_base_token().address,\n            quote_token.address,\n        )?;\n        let factory = self.uniswap_v3_factory()?;\n        anyhow::ensure!(\n            pool.dex.factory == factory,\n            \"Restored pool {instrument_id} references factory {}, expected registered factory {factory}\",","sourceCodeStart":1064,"sourceCodeEnd":1100,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/execution/client.rs#L1064-L1100","documentation":"restore_swap_plan needs the Uniswap V3 fee tier (U24) of the restored pool to build the swap parameters. If the resolved pool has no fee value (pool.fee is None), the swap plan cannot be constructed and reconciliation aborts. The library throws this because a Uniswap V3 swap cannot be encoded without a fee tier.","triggerScenarios":"reconcile_unresolved_execution or build_execution_verification_migration calls restore_swap_plan; resolve_pool(&instrument_id) returns a pool whose fee field is None. Happens when the pool definition for the instrument is incomplete in the instrument provider/cache, e.g. fee not queried/set at registration or a partially-defined instrument restored from cache.","commonSituations":"Instrument provider configured without fee discovery (fee never populated for that pool); custom/edited instrument definitions missing the fee attribute; adapter version where fee was optional combined with a pool source that omits it; cache restored from an incomplete snapshot.","solutions":["Fix the instrument/pool registration so the Uniswap V3 fee tier is populated (re-register the pool or enable fee discovery) and restart.","Verify the instrument provider config points at the correct factory/pool so fee metadata is fetched.","Restore a complete cache snapshot that includes the pool's fee metadata.","As a last resort, resolve the pending intent manually in the durable store, since the swap cannot be rebuilt from a fee-less pool."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"let pool = client.resolve_pool(&instrument_id)?;\nif pool.fee.is_none() {\n    eprintln!(\"pool for {instrument_id} has no fee tier; fix instrument registration before connecting\");\n}","typeGuard":"fn has_fee(pool: &Pool) -> bool {\n    pool.fee.is_some()\n}","tryCatchPattern":null,"preventionTips":["Enable fee discovery or explicitly set the Uniswap V3 fee tier when registering pools","Validate instrument definitions (fee present) at startup before live trading","Restore complete cache snapshots including pool metadata","Test reconciliation against a copy of the durable store after any instrument-provider change"],"tags":["uniswap-v3","missing-field","pool-metadata","reconciliation"],"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-23T08:17:48.524Z"}