{"record":{"id":"d5f1be825f654eea","repo":"nautechsystems/nautilus_trader","slug":"persisted-swap-intent-has-no-input-amount","errorCode":null,"errorMessage":"Persisted swap intent has no input amount","messagePattern":"Persisted swap intent has no input amount","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/execution/client.rs","lineNumber":1078,"sourceCode":"        );\n\n        let pool = self.resolve_pool(&instrument_id)?;\n        let pool_address = Address::from_str(\n            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        )?;","sourceCodeStart":1060,"sourceCodeEnd":1096,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/execution/client.rs#L1060-L1096","documentation":"restore_swap_plan parses the persisted amount_in (as a U256 decimal string) to reconstruct the swap's input amount. If the intent row has no amount_in value, the swap plan cannot be rebuilt and reconciliation fails. The library requires this field because re-driving the swap needs the exact input amount that was originally prepared.","triggerScenarios":"reconcile_unresolved_execution (from connect) or build_execution_verification_migration encounters an active ExecutionIntentRow with intent.amount_in = None when calling restore_swap_plan. Occurs with rows from older schema versions, partial writes, or manual DB manipulation.","commonSituations":"Adapter upgrade from a schema that did not persist amount_in while old rows remain; an interrupted insert when the intent was created; manual database cleanup dropping the value; running a mismatched adapter version against an old database.","solutions":["Mark the intent recoverable or remove it so reconciliation skips it; the plan cannot be restored without the amount.","Backfill amount_in on the row from original trade/swap records if reconciliation of that swap is required.","Confirm intent.schema_version matches EXECUTION_SCHEMA_VERSION and run any required migration before reuse.","Always create intents through the adapter so all required columns are populated atomically."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if intent.amount_in.is_none() {\n    eprintln!(\"intent {} lacks amount_in; swap cannot be rebuilt - backfill or mark recoverable\", intent.id);\n}","typeGuard":"fn has_amount_in(intent: &ExecutionIntentRow) -> bool {\n    intent.amount_in.as_deref().map(|s| !s.is_empty()).unwrap_or(false)\n}","tryCatchPattern":"// Treat a missing amount as unrecoverable and quarantine the row\nmatch restore_swap_plan(&intent) {\n    Err(e) if e.to_string().contains(\"no input amount\") => mark_intent_recoverable(&intent),\n    Err(e) => return Err(e),\n    Ok(plan) => drive(plan),\n}","preventionTips":["Apply schema migrations before reusing an older durable store","Let writes of intent rows complete atomically (adapter-managed inserts only)","Keep adapter and database schema versions in lockstep","Backfill missing columns from trade records before reconnect"],"tags":["persistence","missing-field","reconciliation","uniswap-v3"],"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"}