{"record":{"id":"0b379f0640260412","repo":"huggingface/candle","slug":"if-node-is-malformed-branch-outputs-don","errorCode":null,"errorMessage":"If node {:?} is malformed: branch outputs ({}) don't match node outputs ({})","messagePattern":"If node (.+?) is malformed: branch outputs \\((.+?)\\) don't match node outputs \\((.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"candle-onnx/src/eval.rs","lineNumber":1174,"sourceCode":"                values.insert(node.output[0].clone(), output);\n            }\n            // https://github.com/onnx/onnx/blob/main/docs/Operators.md#identity\n            \"Identity\" => {\n                let input = get(&node.input[0])?;\n                values.insert(node.output[0].clone(), input.clone());\n            }\n            // https://github.com/onnx/onnx/blob/main/docs/Operators.md#if\n            \"If\" => {\n                // protobuf encodes boolean false as 0 and true as 1\n                let cond = to_scalar_flexible::<u8>(&get(&node.input[0])?.get(0)?)?;\n                let attr_name = if cond != 0 {\n                    \"then_branch\"\n                } else {\n                    \"else_branch\"\n                };\n                let sub_graph = get_attr::<GraphProto>(node, attr_name)?;\n                if sub_graph.output.len() != node.output.len() {\n                    bail!(\n                        \"If node {:?} is malformed: branch outputs ({}) don't match node outputs ({})\",\n                        node.name,\n                        sub_graph.output.len(),\n                        node.output.len()\n                    );\n                }\n                let branch_out = simple_eval_(sub_graph, values)?;\n                for (i, out) in node.output.iter().enumerate() {\n                    values.insert(\n                        out.clone(),\n                        branch_out.get(&sub_graph.output[i].name).unwrap().clone(),\n                    );\n                }\n            }\n            // https://github.com/onnx/onnx/blob/main/docs/Operators.md#pad\n            \"Pad\" => {\n                let mode = get_attr_opt(node, \"mode\")?.unwrap_or(\"constant\");\n                let data = get(&node.input[0])?;","sourceCodeStart":1156,"sourceCodeEnd":1192,"githubUrl":"https://github.com/huggingface/candle/blob/d5fee525bfde3273eb7c9b75fd2bc4937be867ca/candle-onnx/src/eval.rs#L1156-L1192","documentation":"When evaluating an ONNX If node, candle-onnx validates that the chosen sub-graph (then_branch or else_branch) declares the same number of outputs as the If node itself. A mismatch means the graph is structurally malformed and the branch result cannot be bound to the node outputs.","triggerScenarios":"Evaluating a model with an If node whose selected sub_graph.output list length differs from node.output length (checked before the condition is even evaluated).","commonSituations":"Hand-assembled or tool-mangled control-flow graphs; exporters from frameworks with divergent branch output counts; an optimizer pass that removed outputs from one branch only.","solutions":["Fix the If node so both branches declare the same outputs as the If node (in count and order)","Validate the model with onnx.checker / onnx.shape_inference to locate the malformed If","Re-export the model from the source framework rather than editing the Protobuf by hand","Run the ONNX optimizer pass that normalizes If sub-graph outputs"],"exampleFix":"// before: else_branch has 1 output, If node declares 2\n// after: add the missing ValueInfoProto to else_branch.output so counts match","handlingStrategy":"validation","validationCode":"for node in &graph.node {\n    if node.op_type == \"If\" {\n        for attr in [\"then_branch\", \"else_branch\"] {\n            let g: &onnx_pb::GraphProto = get_attr(node, attr).unwrap();\n            assert_eq!(g.output.len(), node.output.len(), \"If {} {} output mismatch\", node.name, attr);\n        }\n    }\n}","typeGuard":"fn if_node_well_formed(node: &NodeProto, then_g: &GraphProto, else_g: &GraphProto) -> bool {\n    then_g.output.len() == node.output.len() && else_g.output.len() == node.output.len()\n}","tryCatchPattern":null,"preventionTips":["Run onnx.checker and onnx.shape_inference on control-flow models","Never hand-edit If sub-graph outputs; regenerate from source","Both branches must produce identical output signatures"],"tags":["onnx","if","control-flow","malformed-graph"],"backgroundTag":"malformed-onnx-graph","analyzedSha":"d5fee525bfde3273eb7c9b75fd2bc4937be867ca","analyzedAt":"2026-09-02T00:15:47.023Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}