nautechsystems/nautilus_trader · error

Deployment manifest call edge is invalid

Error message

Deployment manifest call edge is invalid

What it means

Each call edge in the deployment manifest must have a known purpose (one of "wrap", "approve", "swap_sell", "swap_buy") and a known call type (one of "call", "staticcall", "delegatecall", "callcode"). The library rejects any edge with an unrecognized value in either field because the router's simulation and execution logic dispatch on these exact string enums.

Source

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

            &pool.token1,
            &pool.factory,
            &pool.quote_contract,
        ] {
            let address = Address::from_str(address)
                .map_err(|_| anyhow::anyhow!("Pool manifest address is invalid"))?;
            anyhow::ensure!(
                contract_addresses.contains(&address),
                "Pool manifest references an unpinned contract"
            );
        }
        anyhow::ensure!(
            pool.fee != 0 && pool.fee <= 1_000_000,
            "Pool fee is invalid"
        );
    }
    let mut call_edges = HashSet::new();
    for edge in &manifest.call_edges {
        anyhow::ensure!(
            matches!(
                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"
            );

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Set edge.purpose to exactly one of "wrap", "approve", "swap_sell", "swap_buy"
  2. Set edge.call_type to exactly one of "call", "staticcall", "delegatecall", "callcode" (all lowercase)
  3. Remove edges that use purposes this manifest format does not support
  4. Regenerate the manifest with the official generator instead of authoring edges manually

Example fix

// before
{"purpose": "swap", "call_type": "DELEGATECALL"}
// after
{"purpose": "swap_sell", "call_type": "delegatecall"}
Defensive patterns

Strategy: validation

Validate before calling

const PURPOSES: &[&str] = &["wrap", "approve", "swap_sell", "swap_buy"];
const CALL_TYPES: &[&str] = &["call", "staticcall", "delegatecall", "callcode"];
for edge in &manifest.call_edges {
    if !PURPOSES.contains(&edge.purpose.as_str()) {
        return Err(format!("unknown purpose: {}", edge.purpose));
    }
    if !CALL_TYPES.contains(&edge.call_type.as_str()) {
        return Err(format!("unknown call_type: {}", edge.call_type));
    }
}

Type guard

fn is_valid_edge(edge: &CallEdge) -> bool {
    matches!(edge.purpose.as_str(), "wrap" | "approve" | "swap_sell" | "swap_buy")
        && matches!(edge.call_type.as_str(), "call" | "staticcall" | "delegatecall" | "callcode")
}

Try / catch

match validate_deployment_manifest(&manifest) {
    Err(e) if e.to_string().contains("call edge is invalid") => {
        eprintln!("Edge purpose/call_type must use the exact lowercase enum strings: {e}");
    }
    Err(e) => return Err(e),
    Ok(()) => {}
}

Prevention

When it happens

Trigger: Validating a manifest whose call_edges entries contain a purpose or call_type string outside the allowed sets — e.g. a typo like "swapp_sell", a renamed purpose like "swap", or a call type like "CALL" or "create".

Common situations: Hand-writing or hand-editing call edges and misspelling an enum value; tools from another system emitting different call-type vocabulary (uppercase, "delegate_call"); adding a new edge kind before the validator's enum list supports it.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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