huggingface/candle · error
If node {:?} is malformed: branch outputs ({}) don't match n
Error message
If node {:?} is malformed: branch outputs ({}) don't match node outputs ({}) What it means
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.
Source
Thrown at candle-onnx/src/eval.rs:1174
values.insert(node.output[0].clone(), output);
}
// https://github.com/onnx/onnx/blob/main/docs/Operators.md#identity
"Identity" => {
let input = get(&node.input[0])?;
values.insert(node.output[0].clone(), input.clone());
}
// https://github.com/onnx/onnx/blob/main/docs/Operators.md#if
"If" => {
// protobuf encodes boolean false as 0 and true as 1
let cond = to_scalar_flexible::<u8>(&get(&node.input[0])?.get(0)?)?;
let attr_name = if cond != 0 {
"then_branch"
} else {
"else_branch"
};
let sub_graph = get_attr::<GraphProto>(node, attr_name)?;
if sub_graph.output.len() != node.output.len() {
bail!(
"If node {:?} is malformed: branch outputs ({}) don't match node outputs ({})",
node.name,
sub_graph.output.len(),
node.output.len()
);
}
let branch_out = simple_eval_(sub_graph, values)?;
for (i, out) in node.output.iter().enumerate() {
values.insert(
out.clone(),
branch_out.get(&sub_graph.output[i].name).unwrap().clone(),
);
}
}
// https://github.com/onnx/onnx/blob/main/docs/Operators.md#pad
"Pad" => {
let mode = get_attr_opt(node, "mode")?.unwrap_or("constant");
let data = get(&node.input[0])?;View on GitHub (pinned to d5fee525bf)
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
Example fix
// before: else_branch has 1 output, If node declares 2 // after: add the missing ValueInfoProto to else_branch.output so counts match
Defensive patterns
Strategy: validation
Validate before calling
for node in &graph.node {
if node.op_type == "If" {
for attr in ["then_branch", "else_branch"] {
let g: &onnx_pb::GraphProto = get_attr(node, attr).unwrap();
assert_eq!(g.output.len(), node.output.len(), "If {} {} output mismatch", node.name, attr);
}
}
} Type guard
fn if_node_well_formed(node: &NodeProto, then_g: &GraphProto, else_g: &GraphProto) -> bool {
then_g.output.len() == node.output.len() && else_g.output.len() == node.output.len()
} Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- attribute {} was of type TENSOR, but no tensor was found
- attribute {} of type TENSOR was an invalid data_type number
- attribute {} of type TENSOR has an unsupported data_type {}
- attribute {} of type TENSOR has a negative dimension, which
- cannot find the '{name}' attribute in '{}' for {}
AI-assisted analysis of huggingface/candle@d5fee525bf (2026-09-02).
Data as JSON: /api/errors/0b379f0640260412.
Report an issue: GitHub.