{"record":{"id":"115b34177b288acd","repo":"nautechsystems/nautilus_trader","slug":"duplicate-quote-spend-limit-for-token-pair-token","errorCode":null,"errorMessage":"Duplicate quote spend limit for token pair {token_in} -> {token_out}","messagePattern":"Duplicate quote spend limit for token pair (.+?) -> (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/execution/client.rs","lineNumber":332,"sourceCode":"                );\n            }\n            let max_amount = U256::from_str(&limit.max_amount).map_err(|_| {\n                anyhow::anyhow!(\n                    \"Quote spend limit `max_amount` '{}' exceeds the U256 range\",\n                    limit.max_amount\n                )\n            })?;\n            let ceiling = QuoteSpendCeiling {\n                spend_token,\n                spend_token_decimals: limit.spend_token_decimals,\n                max_amount,\n            };\n\n            if parsed_quote_spend_limits\n                .insert((token_in, token_out), ceiling)\n                .is_some()\n            {\n                anyhow::bail!(\n                    \"Duplicate quote spend limit for token pair {token_in} -> {token_out}\"\n                );\n            }\n        }\n\n        if slippage_bps > max_slippage_bps {\n            anyhow::bail!(\n                \"`slippage_bps` {slippage_bps} exceeds `max_slippage_bps` {max_slippage_bps}\"\n            );\n        }\n\n        if max_slippage_bps >= BPS_DENOMINATOR {\n            anyhow::bail!(\"`max_slippage_bps` {max_slippage_bps} must be below {BPS_DENOMINATOR}\");\n        }\n\n        if !(1..=4_095).contains(&max_quote_age_blocks) {\n            anyhow::bail!(\"`max_quote_age_blocks` must be in 1..=4095\");\n        }","sourceCodeStart":314,"sourceCodeEnd":350,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/execution/client.rs#L314-L350","documentation":"Each (token_in, token_out) pair may have at most one quote spend limit; the parsed map insert returns Some on a duplicate key. The library throws this to keep the limits map unambiguous rather than silently overwriting a ceiling.","triggerScenarios":"Calling new/transaction_limits with config.quote_spend_limits containing two entries whose validated (token_in, token_out) pairs are equal (e.g. same addresses differing only in checksum casing before validation).","commonSituations":"Merged config files appending duplicate limit blocks; same pair listed twice with different max_amounts by mistake; duplicated entries after YAML/TOML merge tooling.","solutions":["Remove the duplicate quote_spend_limits entry, keeping the stricter (smaller) max_amount if unsure","Deduplicate the list before writing config (unique by token pair)","Check config merge/diff tooling for accidental duplication"],"exampleFix":"// before\nquote_spend_limits = [\n  { token_in = \"0xA\", token_out = \"0xB\", spend_token = \"0xA\", max_amount = \"100\" },\n  { token_in = \"0xA\", token_out = \"0xB\", spend_token = \"0xA\", max_amount = \"200\" }\n]\n// after\nquote_spend_limits = [\n  { token_in = \"0xA\", token_out = \"0xB\", spend_token = \"0xA\", max_amount = \"100\" }\n]","handlingStrategy":"validation","validationCode":"let mut seen = HashSet::new();\nfor l in &cfg.quote_spend_limits {\n    if !seen.insert((l.token_in.clone(), l.token_out.clone())) {\n        return Err(format!(\"duplicate quote spend limit for {} -> {}\", l.token_in, l.token_out));\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Deduplicate limits in the config build pipeline (e.g. BTreeMap keyed by pair)","Watch for duplicates introduced by merging environment overlays","Keep one limit block per pair in the canonical config"],"tags":["config","validation","duplicate"],"backgroundTag":"conflicting-config-options","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}