nautechsystems/nautilus_trader · error · anyhow::Error
Deployment manifest must contain exactly one {description} c
Error message
Deployment manifest must contain exactly one {description} contract What it means
`validate_manifest_contracts` builds a `singleton` helper that resolves a contract role to exactly one address. When the set of addresses for a given role in the deployment manifest does not have length exactly 1 (zero entries or more than one), `anyhow::ensure!` fails with this message naming the role's description (e.g. 'wrapped native', 'factory', 'quote'). Singleton roles must appear exactly once in the manifest.
Source
Thrown at crates/adapters/blockchain/src/execution/client.rs:386
) -> anyhow::Result<()> {
let verification = config.verification.as_ref().ok_or_else(|| {
anyhow::anyhow!("Independent Blockchain execution verification is required")
})?;
let manifest = &verification.deployment_manifest;
let role_addresses = |role| {
manifest
.contracts
.iter()
.filter(|contract| contract.role == role)
.map(|contract| {
Address::from_str(&contract.address)
.map_err(|_| anyhow::anyhow!("Deployment manifest address is invalid"))
})
.collect::<anyhow::Result<HashSet<_>>>()
};
let singleton = |role, description: &str| {
let addresses = role_addresses(role)?;
anyhow::ensure!(
addresses.len() == 1,
"Deployment manifest must contain exactly one {description} contract"
);
Ok(*addresses.iter().next().expect("singleton role address"))
};
let configured_routers = routers.iter().copied().collect::<HashSet<_>>();
anyhow::ensure!(
role_addresses(BlockchainContractRole::Router)? == configured_routers,
"Deployment manifest router set does not match `router_addresses`"
);
anyhow::ensure!(
singleton(BlockchainContractRole::WrappedNative, "wrapped native")? == weth,
"Deployment manifest wrapped native contract does not match `weth_address`"
);
let factory = singleton(BlockchainContractRole::Factory, "factory")?;
let registered_factory =
crate::exchanges::get_dex_extended(config.chain.name, &DexType::UniswapV3)View on GitHub (pinned to 18893faf8b)
Solutions
- Ensure the manifest contains exactly one `contracts` entry with the required role (factory, quote, or wrapped native)
- Remove duplicate contracts entries that share the same role
- Regenerate the manifest for the target chain so all singleton roles are present exactly once
Example fix
// before: two factory entries
{"role": "Factory", "address": "0xAAA..."},
{"role": "Factory", "address": "0xBBB..."}
// after: exactly one
{"role": "Factory", "address": "0xAAA..."} Defensive patterns
Strategy: validation
Validate before calling
fn check_singletons(contracts: &[ContractEntry], role: BlockchainContractRole) -> Result<(), String> {
let n = contracts.iter().filter(|c| c.role == role).count();
if n != 1 { Err(format!("role {role:?} appears {n} times, expected 1")) } else { Ok(()) }
} Try / catch
match result { Err(e) if e.to_string().contains("exactly one") => { /* fix manifest: add/remove duplicate role entry */ }, Err(e) => return Err(e), Ok(v) => v } Prevention
- After editing a manifest, count entries per role and assert exactly one factory/quote/wrapped-native
- Never merge manifests for the same chain without deduplicating roles
- Use a JSON schema that enforces unique roles
When it happens
Trigger: Running client validation where `manifest.contracts` contains no contract with the requested `BlockchainContractRole`, or contains multiple contracts sharing that role (duplicate factory/router-family entries), or a `description` placeholder renders the role name into the message.
Common situations: Merging two deployment manifests and keeping both factory entries; deleting the Quote contract entry when trimming the manifest; forgetting to add the WrappedNative contract for a new chain; a misconfigured `role` field meaning the expected role is missing while another role has duplicates.
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
- Deployment manifest address is invalid
- Deployment manifest token address is invalid
- Deployment manifest has no wrapped native token identity
- heartbeat_secs must be positive when set
- signature_expiry_secs {signature_expiry_secs}s must be great
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/f85d50302fbe5689.
Report an issue: GitHub.