{"record":{"id":"d916579c35ee3a9b","repo":"huggingface/candle","slug":"reshape-at-most-one-dimension-of-the-target-shape","errorCode":null,"errorMessage":"Reshape: at most one dimension of the target shape can be -1","messagePattern":"Reshape: at most one dimension of the target shape can be -1","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"candle-onnx/src/eval.rs","lineNumber":406,"sourceCode":"                values.insert(node.output[0].clone(), xs);\n            }\n            \"MatMul\" => {\n                let input0 = get(&node.input[0])?;\n                let input1 = get(&node.input[1])?;\n                let output = input0.broadcast_matmul(input1)?;\n                values.insert(node.output[0].clone(), output);\n            }\n            \"Reshape\" => {\n                let input0 = get(&node.input[0])?;\n                let input1 = get(&node.input[1])?.to_vec1::<i64>()?;\n                // A 0 in the target shape copies the corresponding input dimension, unless\n                // allowzero=1, where it means a literal zero-length dimension.\n                let allowzero = get_attr_opt::<i64>(node, \"allowzero\")?\n                    .copied()\n                    .unwrap_or(0)\n                    == 1;\n                if input1.iter().filter(|&&v| v == -1).count() > 1 {\n                    bail!(\"Reshape: at most one dimension of the target shape can be -1\")\n                }\n                // Resolve everything but -1 first: a copied 0 is part of the volume, so it\n                // has to be in the product that -1 is inferred against.\n                let mut resolved: Vec<Option<usize>> = Vec::with_capacity(input1.len());\n                for (idx, &v) in input1.iter().enumerate() {\n                    resolved.push(match v {\n                        -1 => None,\n                        0 if allowzero => Some(0),\n                        0 => Some(input0.dim(idx)?),\n                        v if v > 0 => Some(v as usize),\n                        v => bail!(\"Reshape: invalid dimension {v} in target shape\"),\n                    });\n                }\n                let known: usize = resolved.iter().flatten().product();\n                let input1 = resolved\n                    .into_iter()\n                    .map(|d| match d {\n                        Some(d) => Ok(d),","sourceCodeStart":388,"sourceCodeEnd":424,"githubUrl":"https://github.com/huggingface/candle/blob/d5fee525bfde3273eb7c9b75fd2bc4937be867ca/candle-onnx/src/eval.rs#L388-L424","documentation":"The Reshape op implementation enforces the ONNX rule that the target shape tensor may contain at most one -1 (a dimension whose size is inferred from the remaining volume). If more than one -1 appears, the shape is mathematically ambiguous and the evaluator bails with this message.","triggerScenarios":"simple_eval on a model whose Reshape node receives a shape input containing two or more -1 entries — from an invalid constant, a wrongly computed dynamic shape, or a hand-edited shape tensor.","commonSituations":"Dynamic shape computation bugs where the shape tensor is built at runtime (e.g. concatenating [-1] twice); exporters or scripts generating reshape constants incorrectly; manual model surgery.","solutions":["Fix the shape input so only one dimension is -1; replace the others with concrete sizes or 0 (copy from input, respecting allowzero semantics).","If the shape is computed at runtime, debug the shape-producing nodes and ensure exactly one inferred dim.","Validate the model with onnx.checker to catch the malformed Reshape constant.","If the -1s are intentional for a dynamic axis, restructure the reshape (e.g. use Squeeze/Unsqueeze or Split) so at most one dim is inferred."],"exampleFix":"// before\n# shape constant: [-1, -1, 768]  (invalid)\n// after\n# shape constant: [-1, seq, 768] or [batch, seq, 768] with only one -1","handlingStrategy":"try-catch","validationCode":"fn check_reshape_shapes(model: &onnx::ModelProto) -> Vec<String> {\n    let mut bad = vec![];\n    if let Some(g) = &model.graph {\n        for n in &g.node {\n            if n.op_type == \"Reshape\" {\n                for init in &g.initializer {\n                    if n.input.contains(&init.name) {\n                        // count -1 entries in i64 raw data when applicable\n                        if init.data_type == 7 && init.raw_data.len() % 8 == 0 {\n                            let negs = init.raw_data.chunks_exact(8)\n                                .filter(|c| i64::from_le_bytes(c.try_into().unwrap()) == -1).count();\n                            if negs > 1 { bad.push(n.name.clone()); }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    bad\n}","typeGuard":null,"tryCatchPattern":"match simple_eval(&model, inputs) {\n    Err(e) if e.to_string().contains(\"at most one dimension\") => {\n        anyhow::bail!(\"model contains an invalid Reshape target shape with multiple -1s; fix or re-export the model\")\n    }\n    r => r?,\n}","preventionTips":["Ensure Reshape shape tensors contain at most one -1","Debug runtime-computed shape tensors for duplicated inferred dims","Run onnx.checker to catch malformed reshape constants","Restructure dynamic reshapes with Unsqueeze/Squeeze instead of multiple -1s"],"tags":["onnx","reshape","shape-mismatch","eval"],"backgroundTag":"invalid-reshape-shape","analyzedSha":"d5fee525bfde3273eb7c9b75fd2bc4937be867ca","analyzedAt":"2026-09-02T00:15:47.023Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}