{"record":{"id":"e0f6d62c3818b1ac","repo":"nautechsystems/nautilus_trader","slug":"deployment-manifest-call-edge-is-invalid","errorCode":null,"errorMessage":"Deployment manifest call edge is invalid","messagePattern":"Deployment manifest call edge is invalid","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/rpc/verification.rs","lineNumber":1390,"sourceCode":"            &pool.token1,\n            &pool.factory,\n            &pool.quote_contract,\n        ] {\n            let address = Address::from_str(address)\n                .map_err(|_| anyhow::anyhow!(\"Pool manifest address is invalid\"))?;\n            anyhow::ensure!(\n                contract_addresses.contains(&address),\n                \"Pool manifest references an unpinned contract\"\n            );\n        }\n        anyhow::ensure!(\n            pool.fee != 0 && pool.fee <= 1_000_000,\n            \"Pool fee is invalid\"\n        );\n    }\n    let mut call_edges = HashSet::new();\n    for edge in &manifest.call_edges {\n        anyhow::ensure!(\n            matches!(\n                edge.purpose.as_str(),\n                \"wrap\" | \"approve\" | \"swap_sell\" | \"swap_buy\"\n            ) && matches!(\n                edge.call_type.as_str(),\n                \"call\" | \"staticcall\" | \"delegatecall\" | \"callcode\"\n            ),\n            \"Deployment manifest call edge is invalid\"\n        );\n        let caller = Address::from_str(&edge.caller)\n            .map_err(|_| anyhow::anyhow!(\"Call edge address is invalid\"))?;\n        let target = Address::from_str(&edge.target)\n            .map_err(|_| anyhow::anyhow!(\"Call edge address is invalid\"))?;\n        for address in [caller, target] {\n            anyhow::ensure!(\n                contract_addresses.contains(&address),\n                \"Call edge references an unpinned contract\"\n            );","sourceCodeStart":1372,"sourceCodeEnd":1408,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/rpc/verification.rs#L1372-L1408","documentation":"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.","triggerScenarios":"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\".","commonSituations":"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.","solutions":["Set edge.purpose to exactly one of \"wrap\", \"approve\", \"swap_sell\", \"swap_buy\"","Set edge.call_type to exactly one of \"call\", \"staticcall\", \"delegatecall\", \"callcode\" (all lowercase)","Remove edges that use purposes this manifest format does not support","Regenerate the manifest with the official generator instead of authoring edges manually"],"exampleFix":"// before\n{\"purpose\": \"swap\", \"call_type\": \"DELEGATECALL\"}\n// after\n{\"purpose\": \"swap_sell\", \"call_type\": \"delegatecall\"}","handlingStrategy":"validation","validationCode":"const PURPOSES: &[&str] = &[\"wrap\", \"approve\", \"swap_sell\", \"swap_buy\"];\nconst CALL_TYPES: &[&str] = &[\"call\", \"staticcall\", \"delegatecall\", \"callcode\"];\nfor edge in &manifest.call_edges {\n    if !PURPOSES.contains(&edge.purpose.as_str()) {\n        return Err(format!(\"unknown purpose: {}\", edge.purpose));\n    }\n    if !CALL_TYPES.contains(&edge.call_type.as_str()) {\n        return Err(format!(\"unknown call_type: {}\", edge.call_type));\n    }\n}","typeGuard":"fn is_valid_edge(edge: &CallEdge) -> bool {\n    matches!(edge.purpose.as_str(), \"wrap\" | \"approve\" | \"swap_sell\" | \"swap_buy\")\n        && matches!(edge.call_type.as_str(), \"call\" | \"staticcall\" | \"delegatecall\" | \"callcode\")\n}","tryCatchPattern":"match validate_deployment_manifest(&manifest) {\n    Err(e) if e.to_string().contains(\"call edge is invalid\") => {\n        eprintln!(\"Edge purpose/call_type must use the exact lowercase enum strings: {e}\");\n    }\n    Err(e) => return Err(e),\n    Ok(()) => {}\n}","preventionTips":["Use the library's enum/constant types for purpose and call_type instead of raw strings","Lint manifests for uppercase or snake_case variants of the enum values","Copy enum values from the validator source, never from memory"],"tags":["blockchain","manifest-validation","enum"],"backgroundTag":"invalid-enum-value","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}