{"record":{"id":"cadb02b5417259c7","repo":"huggingface/candle","slug":"slice-assign-requires-input-with-the-same-rank","errorCode":null,"errorMessage":"slice-assign requires input with the same rank {} <> {}","messagePattern":"slice-assign requires input with the same rank (.+?) <> (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"candle-core/src/tensor.rs","lineNumber":2870,"sourceCode":"        } else {\n            let last = rank - 1;\n            let t = self.transpose(dim, last)?;\n            let t = t.broadcast_matmul(&triu)?;\n            t.transpose(dim, last)\n        }\n    }\n\n    /// Returns a copy of `self` where the values within `ranges` have been replaced with the\n    /// content of `src`.\n    pub fn slice_assign<D: std::ops::RangeBounds<usize>>(\n        &self,\n        ranges: &[D],\n        src: &Tensor,\n    ) -> Result<Self> {\n        let src_dims = src.dims();\n        let self_dims = self.dims();\n        if self_dims.len() != src_dims.len() {\n            bail!(\n                \"slice-assign requires input with the same rank {} <> {}\",\n                self_dims.len(),\n                src_dims.len()\n            )\n        }\n        if self_dims.len() != ranges.len() {\n            bail!(\n                \"slice-assign requires input with the same rank as there are ranges {} <> {}\",\n                self_dims.len(),\n                ranges.len()\n            )\n        }\n        let mut src = src.clone();\n        let mut mask = Self::ones(src.shape(), DType::U8, src.device())?;\n        for (i, range) in ranges.iter().enumerate() {\n            let start_included = match range.start_bound() {\n                std::ops::Bound::Unbounded => 0,\n                std::ops::Bound::Included(v) => *v,","sourceCodeStart":2852,"sourceCodeEnd":2888,"githubUrl":"https://github.com/huggingface/candle/blob/d5fee525bfde3273eb7c9b75fd2bc4937be867ca/candle-core/src/tensor.rs#L2852-L2888","documentation":"Tensor::slice_assign writes a source tensor into a rectangular region of self defined by ranges. Both tensors must have the same number of dimensions, because each dim of src is matched pairwise with a range and a dim of self. When ranks differ, the method bails reporting self's rank and src's rank.","triggerScenarios":"tensor.slice_assign(&[(0..2)?], &src) where src.rank() != self.rank(), e.g. assigning a 1-D vector into a 2-D tensor region.","commonSituations":"Forgetting to unsqueeze src before slice-assigning into a batched tensor; passing a scalar/1-D row where a rank-N slice was required; shape refactors after adding a batch dimension.","solutions":["Unsqueeze or reshape src so its rank equals self's rank","Verify both shapes with t.dims().len() == src.dims().len() before the call","Use tensor.narrow/cat to build the result if a full reassignment is simpler"],"exampleFix":"// before\nt.slice_assign(&(0..2, 1..3), &src)?; // src is rank 1\n// after\nlet src = src.unsqueeze(0)?; // now rank 2\nt.slice_assign(&(0..2, 1..3), &src)?;","handlingStrategy":"validation","validationCode":"if src.dims().len() != t.dims().len() {\n    panic!(\"rank mismatch: {} vs {}\", t.dims().len(), src.dims().len());\n}","typeGuard":null,"tryCatchPattern":"let src = if src.dims().len() != t.dims().len() { src.unsqueeze(0)? } else { src };\nt.slice_assign(ranges, &src)?;","preventionTips":["Unsqueeze src explicitly before slice-assign into higher-rank tensors","Compare ranks in debug_assert! when building slicing code","Keep helper wrappers that pad src's rank automatically"],"tags":["rust","candle","slice-assign","rank-mismatch"],"backgroundTag":"tensor-rank-mismatch","analyzedSha":"d5fee525bfde3273eb7c9b75fd2bc4937be867ca","analyzedAt":"2026-09-02T00:15:47.023Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}