{"record":{"id":"4858adcc28c534f3","repo":"nautechsystems/nautilus_trader","slug":"swap-quote-failed-for-instrument-id-e","errorCode":null,"errorMessage":"Swap quote failed for {instrument_id}: {e}","messagePattern":"Swap quote failed for (.+?): (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/execution/client.rs","lineNumber":1255,"sourceCode":"                    \"No pool profiler for {instrument_id}; an active data subscription is required to quote the swap\"\n                )\n            })?;\n\n        if !profiler.is_initialized {\n            anyhow::bail!(\"Pool profiler for {instrument_id} is not initialized\");\n        }\n        let profiler_block = profiler\n            .last_processed_event\n            .as_ref()\n            .map(|position| position.number)\n            .ok_or_else(|| {\n                anyhow::anyhow!(\"Pool profiler for {instrument_id} has processed no events\")\n            })?;\n\n        let zero_for_one = base_token.address == pool.token0.address;\n        let quote = profiler\n            .swap_exact_in(amount_in, zero_for_one, None)\n            .map_err(|e| anyhow::anyhow!(\"Swap quote failed for {instrument_id}: {e}\"))?;\n\n        let amount_filled = if zero_for_one {\n            quote.amount0\n        } else {\n            quote.amount1\n        };\n\n        if amount_filled != I256::from(amount_in) {\n            anyhow::bail!(\n                \"Local quote for {instrument_id} filled {amount_filled} of the {amount_in} order amount; pool liquidity cannot fill the order\"\n            );\n        }\n\n        let quoted_amount_out = exact_output_amount(&quote, zero_for_one)?;\n        let min_amount_out = derive_min_amount_out(quoted_amount_out, slippage_bps)?;\n\n        self.ensure_transaction_ready(TransactionPurpose::Swap)?;\n","sourceCodeStart":1237,"sourceCodeEnd":1273,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/2114cf6f761429e0adb5ca9596fcd7b895b16011/crates/adapters/blockchain/src/execution/client.rs#L1237-L1273","documentation":"The local pool profiler's swap_exact_in(amount_in, zero_for_one, None) simulation returned an error while trying to quote the exact-input swap. The underlying cause is appended ({e}) and typically comes from the tick-walk math: not enough (or no) liquidity in the direction being traded to consume amount_in within the simulated range, or other arithmetic infeasibility in the local pool state.","triggerScenarios":"submit_order whose amount_in exceeds what the profiler's reconstructed liquidity can absorb in zero_for_one (or the reverse) direction; quoting against a stale/partial pool state after large liquidity removals; amount_in so large the tick walk runs out of initialized ticks.","commonSituations":"Thin single-sided liquidity pools; trading right after an LP burned most liquidity; order sizing derived from a different venue's depth; profiler state lagging recent Swap/Burn events.","solutions":["Reduce the order size and retry; the separate 'filled' check shows how much the pool could actually absorb","Check the pool's current liquidity and tick range on-chain (or via the data feed) to size orders within available depth","Confirm the profiler is current (recent events processed) before concluding liquidity is genuinely insufficient","Route around dead pools: de-list instruments whose profiler repeatedly fails to quote"],"exampleFix":"# before: order sized far above pool depth\nqty = Quantity.from_raw(instrument_id, 10**24)\nself.submit_order(market_order(instrument_id, qty))  # Swap quote failed\n\n# after: size within a fraction of observed fill capacity\nlast_fill_raw = self._observed_max_fill_raw  # tracked from quotes/deltas\nqty = Quantity.from_raw(instrument_id, min(10**24, last_fill_raw // 4))\nself.submit_order(market_order(instrument_id, qty))","handlingStrategy":"validation","validationCode":"# Size orders within observed pool depth before submitting\nlast_quote = self.cache.quote_tick(instrument_id)\nassert last_quote is not None, 'no quote yet'\nmax_raw = int(self._max_observed_fill_raw * 0.25)  # quarter of observed absorption\nassert int(order_qty_raw) <= max_raw, f'{instrument_id}: size exceeds local depth estimate'","typeGuard":null,"tryCatchPattern":"try:\n    self.submit_order(order)\nexcept Exception as e:\n    if 'Swap quote failed' in str(e):\n        self._max_observed_fill_raw //= 2  # back off size and retry next signal\n        return\n    raise","preventionTips":["Track recent fill capacity from quotes/deltas and cap order size to a fraction of it","Skip instruments whose local quote repeatedly fails; treat it as a no-liquidity signal, not a transient error"],"tags":["blockchain","uniswap-v3","swap-quote","liquidity","pool-profiler"],"backgroundTag":"insufficient-liquidity","analyzedSha":"2114cf6f761429e0adb5ca9596fcd7b895b16011","analyzedAt":"2026-08-21T11:28:30.864Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}