nautechsystems/nautilus_trader · error

Deployment manifest contains a duplicate call edge

Error message

Deployment manifest contains a duplicate call edge

What it means

Call edges must be unique: the validator inserts a (purpose, caller, target, call_type) tuple into a HashSet and rejects the manifest if the tuple was already present. Duplicate edges add nothing to the call graph and usually indicate an accidental double entry, so they are treated as a manifest defect.

Source

Thrown at crates/adapters/blockchain/src/rpc/verification.rs:1410

                edge.purpose.as_str(),
                "wrap" | "approve" | "swap_sell" | "swap_buy"
            ) && matches!(
                edge.call_type.as_str(),
                "call" | "staticcall" | "delegatecall" | "callcode"
            ),
            "Deployment manifest call edge is invalid"
        );
        let caller = Address::from_str(&edge.caller)
            .map_err(|_| anyhow::anyhow!("Call edge address is invalid"))?;
        let target = Address::from_str(&edge.target)
            .map_err(|_| anyhow::anyhow!("Call edge address is invalid"))?;
        for address in [caller, target] {
            anyhow::ensure!(
                contract_addresses.contains(&address),
                "Call edge references an unpinned contract"
            );
        }
        anyhow::ensure!(
            call_edges.insert((
                edge.purpose.as_str(),
                caller,
                target,
                edge.call_type.as_str()
            )),
            "Deployment manifest contains a duplicate call edge"
        );
    }

    for purpose in ["swap_sell", "swap_buy"] {
        anyhow::ensure!(
            manifest
                .call_edges
                .iter()
                .any(|edge| edge.purpose == purpose),
            "Deployment manifest is missing a swap call graph"
        );

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Remove the duplicate call_edge entry so each (purpose, caller, target, call_type) combination appears once
  2. If merging manifests, deduplicate call_edges by the four-key tuple before validation
  3. Fix the generator or merge script to deduplicate edges automatically
  4. Diff the call_edges array against a previous valid manifest to spot accidental copies

Example fix

// before
{"call_edges": [{"purpose": "approve", "caller": "0xaaa...", "target": "0xbbb...", "call_type": "call"}, {"purpose": "approve", "caller": "0xaaa...", "target": "0xbbb...", "call_type": "call"}]}
// after
{"call_edges": [{"purpose": "approve", "caller": "0xaaa...", "target": "0xbbb...", "call_type": "call"}]}
Defensive patterns

Strategy: validation

Validate before calling

use std::collections::HashSet;
let mut seen: HashSet<(String, String, String, String)> = HashSet::new();
for edge in &manifest.call_edges {
    let key = (edge.purpose.clone(), edge.caller.clone(), edge.target.clone(), edge.call_type.clone());
    if !seen.insert(key) {
        return Err("duplicate call edge".into());
    }
}

Try / catch

match validate_deployment_manifest(&manifest) {
    Err(e) if e.to_string().contains("duplicate call edge") => {
        eprintln!("Deduplicate call_edges by (purpose, caller, target, call_type): {e}");
    }
    Err(e) => return Err(e),
    Ok(()) => {}
}

Prevention

When it happens

Trigger: Validating a manifest whose call_edges array contains two entries with identical purpose, caller, target, and call_type (differences in any other field do not matter — the dedup key is those four values).

Common situations: Merging manifests or appending generated edges to hand-written ones and duplicating an entry; a generator bug that emits the approve edge twice; copy-paste duplication while editing JSON by hand.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/cf7ba74f23bc4e19. Report an issue: GitHub.