nautechsystems/nautilus_trader · error
Wallet token {address} does not have exactly one deployment
Error message
Wallet token {address} does not have exactly one deployment manifest identity What it means
When building a `Token` from the wallet, the adapter looks up the token address in the deployment manifest and requires exactly one matching identity. This `ensure!` fails when the number of manifest identities whose `address` parses to the given address is zero or greater than one, so the canonical token identity is ambiguous or missing.
Source
Thrown at crates/adapters/blockchain/src/execution/client.rs:4897
"finalized native balance",
)?;
let native_balance = Money::from_u256(native_amount.value, plan.pool.chain.native_currency())?;
let mut decisions = vec![verification_decision(
&native_amount,
Some(included.block_number),
Some(included.block_number),
)];
let mut token_addresses = token_universe.iter().copied().collect::<Vec<_>>();
token_addresses.sort_unstable();
let mut token_balances = Vec::with_capacity(token_addresses.len());
for address in token_addresses {
let identities = executor
.deployment_manifest
.tokens
.iter()
.filter(|identity| Address::from_str(&identity.address).ok() == Some(address))
.collect::<Vec<_>>();
anyhow::ensure!(
identities.len() == 1,
"Wallet token {address} does not have exactly one deployment manifest identity"
);
let identity = identities[0];
let token = Token::new(
plan.pool.chain.clone(),
address,
identity.name.clone(),
identity.symbol.clone(),
identity.decimals,
);
let call = ERC20::balanceOfCall {
account: executor.wallet_address,
}
.abi_encode();
let amount = required_verification(
executor
.verificationView on GitHub (pinned to 18893faf8b)
Solutions
- Deduplicate the token entries in the deployment manifest so the address appears exactly once
- Add the missing token identity to the deployment manifest if it is absent
- Ensure manifest addresses are canonical checksummed/lowercase and parse to the intended `Address`
- Regenerate the manifest from the deployment source rather than editing it by hand
Example fix
// before: manifest with duplicate
{"tokens": [{"address": "0xABC..."}, {"address": "0xABC..."}]}
// after: single canonical entry
{"tokens": [{"address": "0xAbC...", "decimals": 18, "symbol": "WETH"}]} Defensive patterns
Strategy: validation
Validate before calling
// before execution, confirm the token resolves uniquely
let matches: Vec<_> = manifest.tokens.iter()
.filter(|t| Address::from_str(&t.address).ok() == Some(token_address))
.collect();
ensure!(matches.len() == 1, "token {token_address} must appear exactly once in the manifest"); Type guard
fn unique_token_identity(manifest: &DeploymentManifest, address: Address) -> bool {
manifest.tokens.iter()
.filter(|t| Address::from_str(&t.address).ok() == Some(address))
.count() == 1
} Try / catch
if let Err(e) = execute_plan(&plan).await {
if e.to_string().contains("exactly one deployment manifest identity") {
log::error!("fix manifest: deduplicate or add the token identity");
}
} Prevention
- Keep the deployment manifest generated from source; never hand-edit or merge duplicates
- Use canonical (checksummed) addresses consistently in the manifest
- Run a manifest lint step that rejects duplicate token addresses before deployment
- Confirm wallet token addresses match the chain of the manifest in use
When it happens
Trigger: Executing a plan whose pool token address (1) is not present in `deployment_manifest.tokens`, or (2) appears in multiple identity entries (duplicate addresses, e.g. same token listed under different symbols/decimals or duplicated across chains in the manifest).
Common situations: Hand-edited or merged deployment manifest with duplicated token entries; a wallet token address from a testnet manifest used against a mainnet manifest; case/parity handling differences causing `Address::from_str` to resolve two entries to the same address; token added to the manifest twice during a deployment update.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- Allowed token pair {token_in} -> {token_out} is not fully pi
- Deployment manifest has no capability probe target
- Invalid config type for AxExecutionClientFactory. Expected A
- Failed to load active execution intent: {e}
- Failed to start replacement transaction persistence: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/83b3649199345848.
Report an issue: GitHub.