{"record":{"id":"edefcd0aee6aed0a","repo":"nautechsystems/nautilus_trader","slug":"deployment-manifest-is-missing-a-swap-call-graph","errorCode":null,"errorMessage":"Deployment manifest is missing a swap call graph","messagePattern":"Deployment manifest is missing a swap call graph","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/rpc/verification.rs","lineNumber":1422,"sourceCode":"        for address in [caller, target] {\n            anyhow::ensure!(\n                contract_addresses.contains(&address),\n                \"Call edge references an unpinned contract\"\n            );\n        }\n        anyhow::ensure!(\n            call_edges.insert((\n                edge.purpose.as_str(),\n                caller,\n                target,\n                edge.call_type.as_str()\n            )),\n            \"Deployment manifest contains a duplicate call edge\"\n        );\n    }\n\n    for purpose in [\"swap_sell\", \"swap_buy\"] {\n        anyhow::ensure!(\n            manifest\n                .call_edges\n                .iter()\n                .any(|edge| edge.purpose == purpose),\n            \"Deployment manifest is missing a swap call graph\"\n        );\n    }\n    Ok(())\n}\n\nfn validate_identity(identity: &BlockchainProviderIdentity) -> anyhow::Result<()> {\n    anyhow::ensure!(\n        !identity.provider_id.trim().is_empty(),\n        \"Provider ID is required\"\n    );\n    anyhow::ensure!(\n        !identity.operator_id.trim().is_empty(),\n        \"Provider operator ID is required\"","sourceCodeStart":1404,"sourceCodeEnd":1440,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/rpc/verification.rs#L1404-L1440","documentation":"After per-edge validation, the manifest must contain at least one call edge with purpose \"swap_sell\" and at least one with purpose \"swap_buy\". A deployment without both swap directions cannot be used for the router's two-way swap flow, so validation fails with this error.","triggerScenarios":"Validating a manifest whose call_edges only include \"wrap\"/\"approve\" edges (or only one swap direction); this fires even when every individual edge is valid and pinned.","commonSituations":"Authoring a minimal manifest with just approval edges and forgetting the swap graph; a generator configured for one-directional swaps only; accidentally deleting the swap edges while trimming an existing manifest; copying a template where swap edges were removed as examples.","solutions":["Add call edges with purpose \"swap_sell\" and \"swap_buy\" from the router to the swap-capable contract","If your generator supports a swap-flow option, enable it so both directions are emitted","Restore the swap edges from a previously valid manifest for the same deployment","Verify after editing that call_edges contains at least one edge of each required purpose"],"exampleFix":"// before\n{\"call_edges\": [{\"purpose\": \"wrap\", ...}, {\"purpose\": \"approve\", ...}]}\n// after\n{\"call_edges\": [{\"purpose\": \"wrap\", ...}, {\"purpose\": \"approve\", ...}, {\"purpose\": \"swap_sell\", \"caller\": \"0xrouter...\", \"target\": \"0xpool...\", \"call_type\": \"call\"}, {\"purpose\": \"swap_buy\", \"caller\": \"0xrouter...\", \"target\": \"0xpool...\", \"call_type\": \"call\"}]}","handlingStrategy":"validation","validationCode":"for purpose in [\"swap_sell\", \"swap_buy\"] {\n    if !manifest.call_edges.iter().any(|e| e.purpose == purpose) {\n        return Err(format!(\"manifest missing a '{purpose}' call edge\"));\n    }\n}","typeGuard":null,"tryCatchPattern":"match validate_deployment_manifest(&manifest) {\n    Err(e) if e.to_string().contains(\"missing a swap call graph\") => {\n        eprintln!(\"Add both swap_sell and swap_buy call edges to the manifest\");\n    }\n    Err(e) => return Err(e),\n    Ok(()) => {}\n}","preventionTips":["Use the official generator with the full swap flow enabled so both directions are emitted","Check manifest completeness (all four purposes) before submission","Never trim swap edges from template manifests"],"tags":["blockchain","manifest-validation","config"],"backgroundTag":"missing-required-config-field","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"}