{"record":{"id":"f4c8cb9601a3e29c","repo":"nautechsystems/nautilus_trader","slug":"trade-info-not-initialized","errorCode":null,"errorMessage":"Trade info not initialized","messagePattern":"Trade info not initialized","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/model/src/defi/pool_analysis/size_estimator.rs","lineNumber":197,"sourceCode":"/// - The swap simulation fails.\n/// - The trade info or slippage calculation fails.\npub fn slippage_for_size_bps(\n    profiler: &PoolProfiler,\n    size: U256,\n    zero_for_one: bool,\n) -> anyhow::Result<u32> {\n    profiler.check_if_initialized(PoolEventKind::Swap)?;\n\n    if size.is_zero() {\n        return Ok(0);\n    }\n\n    let mut quote = profiler.swap_exact_in(size, zero_for_one, None)?;\n    quote.calculate_trade_info(&profiler.pool.token0, &profiler.pool.token1)?;\n    let trade_info = quote\n        .trade_info\n        .as_ref()\n        .ok_or_else(|| anyhow::anyhow!(\"Trade info not initialized\"))?;\n\n    trade_info.get_slippage_bps()\n}\n\nfn binary_search_for_size(\n    profiler: &PoolProfiler,\n    impact_bps: u32,\n    zero_for_one: bool,\n    config: &EstimationConfig,\n) -> anyhow::Result<BinarySearchState> {\n    // Validate inputs\n    if impact_bps == 0 {\n        anyhow::bail!(\"Impact must be greater than zero\");\n    }\n\n    if impact_bps > 10000 {\n        anyhow::bail!(\"Impact cannot exceed 100% (10000 bps)\");\n    }","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/defi/pool_analysis/size_estimator.rs#L179-L215","documentation":"`slippage_for_size_bps` runs a hypothetical swap through the profiler, then computes trade info and reads `quote.trade_info`. If `calculate_trade_info` did not populate `trade_info` (it remains `None`), the function errors with 'Trade info not initialized' instead of unwrapping. This is an internal invariant failure: the swap/quote flow should always set trade info before slippage is read.","triggerScenarios":"Calling `slippage_for_size_bps` (directly or via `binary_search_for_size` / `size_for_impact_bps_detailed`) where the quote's `calculate_trade_info` step failed silently or was skipped, leaving `quote.trade_info == None`.","commonSituations":"Simulated swaps on pools with zero liquidity or zero spot price where trade-info computation short-circuits; size-estimation searches hitting edge sizes that produce degenerate quotes.","solutions":["Ensure the quote's `calculate_trade_info` succeeds before reading slippage; propagate its `?` result and check `trade_info.is_some()` afterwards.","Verify the pool has liquidity and a non-zero spot price before size estimation; degenerate pools yield no trade info.","Treat the error as a signal to skip that size in the search rather than aborting.","Update to a version where trade-info initialization is guaranteed, or file a bug if it's None after a successful calculate."],"exampleFix":"// before\nlet mut quote = profiler.swap_exact_in(size, zero_for_one, None)?;\nquote.calculate_trade_info(&profiler.pool.token0, &profiler.pool.token1)?;\nlet trade_info = quote.trade_info.as_ref().ok_or_else(|| anyhow::anyhow!(\"Trade info not initialized\"))?;\n// after\nlet mut quote = profiler.swap_exact_in(size, zero_for_one, None)?;\nquote.calculate_trade_info(&profiler.pool.token0, &profiler.pool.token1)?;\nlet Some(trade_info) = quote.trade_info.as_ref() else {\n    return Ok(None); // no trade info for this size; signal caller instead of erroring\n};","handlingStrategy":"type-guard","validationCode":"fn quote_ready(quote: &SwapQuote) -> bool {\n    quote.trade_info.is_some()\n}","typeGuard":"fn has_trade_info(quote: &SwapQuote) -> Option<&SwapTradeInfo> { quote.trade_info.as_ref() }","tryCatchPattern":"let bps = match slippage_for_size_bps(profiler, size, zero_for_one) {\n    Ok(b) => b,\n    Err(e) if e.to_string().contains(\"Trade info not initialized\") => return Ok(None),\n    Err(e) => return Err(e),\n};","preventionTips":["Check pool liquidity/spot price before running size estimation","Always call calculate_trade_info immediately after swap_exact_in and check the result","Handle per-size errors in binary search loops gracefully"],"tags":["defi","slippage","uninitialized-value"],"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-14T00:17:10.932Z"}