{"record":{"id":"157bf8c6e09f3de1","repo":"nautechsystems/nautilus_trader","slug":"deployment-manifest-contains-a-duplicate-token-ide","errorCode":null,"errorMessage":"Deployment manifest contains a duplicate token identity","messagePattern":"Deployment manifest contains a duplicate token identity","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/execution/client.rs","lineNumber":423,"sourceCode":"                .map(|dex| dex.factory)\n                .ok_or_else(|| {\n                    anyhow::anyhow!(\n                        \"No registered Uniswap V3 deployment for chain {}\",\n                        config.chain.name\n                    )\n                })?;\n        anyhow::ensure!(\n            factory == registered_factory,\n            \"Deployment manifest factory does not match the registered Uniswap V3 factory\"\n        );\n        let quote_contract = singleton(BlockchainContractRole::Quote, \"quote\")?;\n\n        let mut token_decimals = HashMap::new();\n\n        for token in &manifest.tokens {\n            let address = Address::from_str(&token.address)\n                .map_err(|_| anyhow::anyhow!(\"Deployment manifest token address is invalid\"))?;\n            anyhow::ensure!(\n                token_decimals.insert(address, token.decimals).is_none(),\n                \"Deployment manifest contains a duplicate token identity\"\n            );\n        }\n        anyhow::ensure!(\n            token_decimals.contains_key(&weth),\n            \"Deployment manifest has no wrapped native token identity\"\n        );\n\n        if let Some(tokens) = &config.tokens {\n            for token in tokens {\n                let address = validate_address(token)?;\n                anyhow::ensure!(\n                    token_decimals.contains_key(&address),\n                    \"Configured token {address} has no deployment manifest identity\"\n                );\n            }\n        }","sourceCodeStart":405,"sourceCodeEnd":441,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/execution/client.rs#L405-L441","documentation":"When populating `token_decimals`, the validator uses `HashMap::insert` and `anyhow::ensure!(insert(...).is_none(), ...)` to reject any address that appears more than once in `manifest.tokens`. This error means two token entries share the same address, so the manifest's token identity set is not unique and decimals would be ambiguous.","triggerScenarios":"Client validation where `manifest.tokens` contains two entries whose parsed `Address` is equal — exact duplicate rows, or the same address listed under two different symbols/decimals.","commonSituations":"Appending a token to the manifest that already exists (merge conflict or script rerun); listing the same contract under wrapped and unwrapped names; copy-paste duplicating a token block with an edited symbol but unchanged address.","solutions":["Remove the duplicate `tokens` entry so each address appears exactly once in the manifest","If both entries were intentional aliases, keep one canonical entry per contract address","Regenerate the manifest token list to deduplicate"],"exampleFix":"// before\n{\"symbol\": \"USDC\", \"address\": \"0xA0b8...eB48\"},\n{\"symbol\": \"USDC_OLD\", \"address\": \"0xA0b8...eB48\"}\n// after\n{\"symbol\": \"USDC\", \"address\": \"0xA0b8...eB48\"}","handlingStrategy":"validation","validationCode":"let mut seen = HashSet::new();\nfor t in &manifest.tokens {\n    let a = Address::from_str(&t.address).unwrap();\n    if !seen.insert(a) { return Err(format!(\"duplicate token address {a}\")); }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Deduplicate the tokens array when regenerating or merging manifests","Key token entries by address in any generation script so duplicates are impossible","Add a uniqueness assertion to manifest CI checks"],"tags":["rust","config","validation","duplicates"],"backgroundTag":"schema-validation-failed","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"}