{"record":{"id":"d8ee06949f3e189c","repo":"huggingface/candle","slug":"dimension-index-dim-is-too-low-for-tensor-rank","errorCode":null,"errorMessage":"dimension index {dim} is too low for tensor rank {rank}","messagePattern":"dimension index (.+?) is too low for tensor rank (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"candle-pyo3/src/lib.rs","lineNumber":196,"sourceCode":"    } else {\n        if (dim as i64) < -index {\n            ::candle::bail!(\"index {index} is too low for tensor dimension {dim}\")\n        }\n        Ok((dim as i64 + index) as usize)\n    }\n}\n\nfn actual_dim(t: &Tensor, dim: i64) -> ::candle::Result<usize> {\n    let rank = t.rank();\n    if 0 <= dim {\n        let dim = dim as usize;\n        if rank <= dim {\n            ::candle::bail!(\"dimension index {dim} is too large for tensor rank {rank}\")\n        }\n        Ok(dim)\n    } else {\n        if (rank as i64) < -dim {\n            ::candle::bail!(\"dimension index {dim} is too low for tensor rank {rank}\")\n        }\n        Ok((rank as i64 + dim) as usize)\n    }\n}\n\n// TODO: Something similar to this should probably be a part of candle core.\ntrait MapDType {\n    type Output;\n    fn f<T: PyWithDType>(&self, t: &Tensor) -> PyResult<Self::Output>;\n\n    fn map(&self, t: &Tensor) -> PyResult<Self::Output> {\n        match t.dtype() {\n            DType::U8 => self.f::<u8>(t),\n            DType::U32 => self.f::<u32>(t),\n            DType::I64 => self.f::<i64>(t),\n            DType::BF16 => self.f::<bf16>(t),\n            DType::F16 => self.f::<f16>(t),\n            DType::F32 => self.f::<f32>(t),","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/huggingface/candle/blob/d5fee525bfde3273eb7c9b75fd2bc4937be867ca/candle-pyo3/src/lib.rs#L178-L214","documentation":"Thrown by candle-pyo3's `actual_dim` when a negative dimension index is more negative than -rank, so it cannot be resolved to a valid axis. This protects index_select, gather, squeeze, narrow, argmax_keepdim and argmin_keepdim from invalid axis references.","triggerScenarios":"Passing dim = -(rank+1) or lower, e.g. dim=-4 on a rank-3 tensor, or dim=-1 on a scalar/0-rank tensor.","commonSituations":"Using -1 for the last axis on tensors that unexpectedly have fewer dimensions (e.g. after an accidental squeeze), or reusing dim constants across tensors of differing rank.","solutions":["Verify tensor rank and ensure -rank <= dim < rank before the call","Use positive dim indices derived from t.rank() instead of negative ones","Check earlier ops (squeeze/reshape) that may have reduced rank unexpectedly"],"exampleFix":"// before\nt.argmax_keepdim(-4)  # rank-3 tensor\n// after\nassert -t.rank() <= -4 < t.rank()  # fails here; use a valid dim\nt.argmax_keepdim(-1)","handlingStrategy":"validation","validationCode":"let rank = t.rank() as i64;\nif !(-rank..rank).contains(&dim) { panic!(\"dim {} invalid for rank {}\", dim, rank); }","typeGuard":"fn is_valid_neg_dim(rank: usize, dim: i64) -> bool {\n    (-(rank as i64)..(rank as i64)).contains(&dim)\n}","tryCatchPattern":"match t.argmax_keepdim(dim) {\n    Ok(v) => v,\n    Err(e) if e.to_string().contains(\"too low\") => fallback_argmax(),\n    Err(e) => return Err(e),\n}","preventionTips":["Compute the last axis as rank-1 explicitly instead of -1 when rank is uncertain","Check rank after ops that may drop dimensions","Centralize dim selection in a helper that validates against rank"],"tags":["rust","pyo3","tensor","negative-dimension"],"backgroundTag":"tensor-dimension-out-of-range","analyzedSha":"d5fee525bfde3273eb7c9b75fd2bc4937be867ca","analyzedAt":"2026-09-02T00:15:47.023Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}