{"record":{"id":"690dd587a9e44919","repo":"nautechsystems/nautilus_trader","slug":"verified-call-trace-contains-an-operation-without","errorCode":null,"errorMessage":"Verified call trace contains an operation without a target","messagePattern":"Verified call trace contains an operation without a target","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"critical","filePath":"crates/adapters/blockchain/src/execution/client.rs","lineNumber":4428,"sourceCode":"            && trace.success == receipt_success,\n        \"Verified call-trace root differs from the authenticated transaction\"\n    );\n    validate_internal_calls(&trace.calls, signed.to, purpose, manifest)\n}\n\nfn validate_internal_calls(\n    calls: &[VerifiedCallTrace],\n    caller_context: Address,\n    purpose: &str,\n    manifest: &BlockchainDeploymentManifest,\n) -> anyhow::Result<()> {\n    for call in calls {\n        anyhow::ensure!(\n            call.from == caller_context,\n            \"Verified call trace child has an invalid caller context\"\n        );\n        let target = call.to.ok_or_else(|| {\n            anyhow::anyhow!(\"Verified call trace contains an operation without a target\")\n        })?;\n        let call_type = match call.call_type {\n            RpcCallType::Call => \"call\",\n            RpcCallType::Callcode => \"callcode\",\n            RpcCallType::Delegatecall => \"delegatecall\",\n            RpcCallType::Staticcall => \"staticcall\",\n            RpcCallType::Create | RpcCallType::Create2 | RpcCallType::Selfdestruct => {\n                anyhow::bail!(\"Verified call trace contains a forbidden state-changing operation\")\n            }\n        };\n        let permitted = manifest.call_edges.iter().any(|edge| {\n            edge.purpose == purpose\n                && edge.call_type.eq_ignore_ascii_case(call_type)\n                && Address::from_str(&edge.caller).ok() == Some(call.from)\n                && Address::from_str(&edge.target).ok() == Some(target)\n        });\n        anyhow::ensure!(\n            permitted,","sourceCodeStart":4410,"sourceCodeEnd":4446,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/execution/client.rs#L4410-L4446","documentation":"This error is raised in `validate_internal_calls` when a child frame in the verified call trace has no target: `call.to` is `None`. Every internal EVM call frame must name the contract (or account) it called; a frame without a target cannot be checked against the deployment manifest's reviewed call edges, so verification cannot proceed and fails explicitly. This guards against malformed tracer output being silently accepted.","triggerScenarios":"`validate_internal_calls` encounters any `VerifiedCallTrace` child whose `to` field is `None` (the `ok_or_else` at client.rs:4427). Happens when the tracing RPC returns frames with a missing/null `to` — typically for CREATE/CREATE2 frames (which legitimately have no `to`) surfacing where the validator expects a CALL/STATICCALL/DELEGATECALL frame, or when the tracer omits the field on malformed input.","commonSituations":"A tracer that reports contract-creation frames without a `to` address feeding into this validator's input; nodes with differing callTracer implementations that leave `to` null on edge cases (precompile calls, self-destruct edge frames); proxy nodes that strip or reformat trace fields; traces for transactions containing contract deployments where the validator's upstream filtering did not exclude creation frames.","solutions":["Inspect the full trace frame at the failure point; if it is a CREATE/CREATE2 frame, note that such operations are separately rejected as forbidden state-changing operations — ensure the tracer's frames are correctly typed so creation frames do not masquerade as calls.","Re-fetch the trace from a node whose callTracer always populates `to` for CALL/STATICCALL/DELEGATECALL frames (e.g. current geth/erigon); upgrade the node if it emits null targets.","Verify the verification coordinator's tracer configuration (tracer type/options) has not dropped the `to` field via custom filtering or field selection.","If precompile or native-frame edge cases produce null targets, confirm the node version and switch to one with correct callTracer semantics before re-running verification."],"exampleFix":"// before: custom tracer that omits `to` on some frames\nlet trace = node.debug_trace_transaction(tx_hash, CustomTracer { fields: &[\"from\", \"input\"] }).await?;\nvalidate_internal_calls(&trace.calls, ctx, purpose, manifest)?; // frames lack `to`\n\n// after: standard callTracer guarantees `to` on call frames\nlet trace = node.debug_trace_transaction(tx_hash, GethCallTracer).await?;\nvalidate_internal_calls(&trace.calls, ctx, purpose, manifest)?;","handlingStrategy":"validation","validationCode":"// Filter/flag frames without targets before verification.\nfn all_children_have_targets(calls: &[VerifiedCallTrace]) -> bool {\n    calls.iter().all(|c| c.to.is_some())\n}","typeGuard":"fn has_target(call: &VerifiedCallTrace) -> bool {\n    call.to.is_some()\n}","tryCatchPattern":"if let Err(e) = validate_internal_calls(&trace.calls, ctx, purpose, manifest) {\n    if e.to_string().contains(\"without a target\") {\n        // usually a CREATE frame or malformed tracer output: re-trace with standard callTracer\n        let fresh = trusted_node.debug_trace_transaction(tx_hash, GethCallTracer).await?;\n        return validate_internal_calls(&fresh.calls, ctx, purpose, manifest);\n    }\n    return Err(e);\n}","preventionTips":["Use a callTracer implementation that always populates `to` for CALL/STATICCALL/DELEGATECALL frames.","Exclude or explicitly reject contract-creation frames before validation (the validator separately forbids them).","Avoid proxies that strip trace fields; fetch traces directly from a full node.","Pin and test the node version used for tracing in CI so frame shape regressions are caught early.","Log frames with null `to` (with call_type) to identify creation vs malformed frames."],"tags":["blockchain","call-trace","evm","trace-validation","malformed-data"],"backgroundTag":"unexpected-response-shape","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}