huggingface/candle · error

empty concat

Error message

empty concat

What it means

The Concat operator evaluator gathers all input tensors of the node; if the node declares no inputs, the minimum-rank computation that follows (inputs.iter().map(...).min().unwrap()) would panic, so the evaluator bails with 'empty concat' instead.

Source

Thrown at candle-onnx/src/eval.rs:994

                    let bs = get(&node.input[2])?;
                    let mut bs_shape = vec![1; ys.rank()];
                    bs_shape[1] = bs.elem_count();
                    ys.broadcast_add(&bs.reshape(bs_shape)?)?
                } else {
                    ys
                };
                values.insert(node.output[0].clone(), ys);
            }
            "Concat" => {
                // https://github.com/onnx/onnx/blob/main/docs/Operators.md#Concat
                let inputs = node
                    .input
                    .iter()
                    .map(|n| Ok(get(n.as_str())?.clone()))
                    .collect::<Result<Vec<Value>>>()?;
                let axis: i64 = *get_attr(node, "axis")?;
                if inputs.is_empty() {
                    bail!("empty concat")
                };
                // Find minimum rank among inputs and squeeze trailing singleton dims to match
                let min_rank = inputs.iter().map(|t| t.rank()).min().unwrap();
                let inputs: Vec<_> = inputs
                    .into_iter()
                    .map(|t| {
                        let mut t = t;
                        while t.rank() > min_rank {
                            let last_dim = t.rank() - 1;
                            if t.dims()[last_dim] == 1 {
                                t = t.squeeze(last_dim).unwrap_or(t);
                            } else {
                                break;
                            }
                        }
                        t
                    })
                    .collect();

View on GitHub (pinned to d5fee525bf)

Solutions

  1. Fix the graph so the Concat node lists at least one input (with all inputs sharing the same rank except on the concat axis)
  2. Regenerate the model correctly with onnx.helper, passing inputs=[...] to make_node
  3. Run the ONNX checker (onnx.checker.check_model) to catch malformed nodes before inference
  4. Remove the dead Concat node if it is unused graph surgery residue

Example fix

// before
node = onnx.helper.make_node('Concat', inputs=[], outputs=['y'], axis=0)
// after
node = onnx.helper.make_node('Concat', inputs=['a', 'b'], outputs=['y'], axis=0)
Defensive patterns

Strategy: validation

Validate before calling

for node in &model.graph.node {
    if node.op_type == "Concat" && node.input.is_empty() {
        panic!("Concat node '{}' has no inputs", node.name);
    }
}

Try / catch

match candle_onnx::simple_eval(&model, &inputs) {
    Err(e) if e.to_string().contains("empty concat") => {
        eprintln!("malformed graph: Concat without inputs: {e}");
    }
    other => other?,
}

Prevention

When it happens

Trigger: Running simple_eval on an ONNX graph containing a Concat node with an empty or missing input list — typically a malformed or corrupted model.

Common situations: Programmatically generated ONNX graphs (graph surgery, quantization passes, model pruning tools) that dropped all Concat inputs; hand-built graphs via onnx.helper with inputs forgotten.

Related errors


AI-assisted analysis of huggingface/candle@d5fee525bf (2026-09-02). Data as JSON: /api/errors/2b22a2c7f70eff5b. Report an issue: GitHub.