huggingface/candle · error
cannot use slice_set when self and src share their storage
Error message
cannot use slice_set when self and src share their storage
What it means
scatter_set mutates self's storage in place, so if self and source share the same underlying storage (e.g. one is a view of the other), in-place writing would corrupt the source data. Candle guards this aliasing case with an explicit bail. Note the message says 'slice_set' — a copy-paste from the sibling op — but it is thrown by Tensor::scatter_set.
Source
Thrown at candle-core/src/tensor.rs:1696
.copy_strided_src(&mut storage, 0, self.layout())?;
let layout = Layout::contiguous(shape);
storage.scatter_set(
&layout,
&indexes.storage(),
indexes.layout(),
&source.storage(),
source.layout(),
dim,
)?;
let op = BackpropOp::new3(self, indexes, source, |t1, t2, t3| {
Op::Scatter(t1, t2, t3, dim)
});
Ok(from_storage(storage, self.shape(), op, false))
}
pub fn scatter_set<D: Dim>(&self, indexes: &Self, source: &Self, dim: D) -> Result<()> {
if self.same_storage(source) {
crate::bail!("cannot use slice_set when self and src share their storage")
}
let dim = dim.to_index(self.shape(), "scatter-set")?;
self.scatter_checks(indexes, source, dim)?;
self.storage_mut().scatter_set(
self.layout(),
&indexes.storage(),
indexes.layout(),
&source.storage(),
source.layout(),
dim,
)?;
Ok(())
}
pub fn scatter_add<D: Dim>(&self, indexes: &Self, source: &Self, dim: D) -> Result<Self> {
let dim = dim.to_index(self.shape(), "scatter-add")?;
self.scatter_checks(indexes, source, dim)?;
let shape = self.shape();View on GitHub (pinned to d5fee525bf)
Solutions
- Make an independent copy of the source first: let src = src.copy()? (or to_device/to_dtype which materialize) so storages differ.
- Use the non-in-place scatter API instead of scatter_set, then assign the result.
- Restructure code so the destination and source are distinct buffers.
Example fix
// before let src = t.i(0..2)?; // shares storage with t t.scatter_set(&idx, &src, 0)?; // error // after let src = t.i(0..2)?.copy()?; t.scatter_set(&idx, &src, 0)?;
Defensive patterns
Strategy: validation
Validate before calling
if t.same_storage(&src) {
let src = src.copy()?;
}
t.scatter_set(&idx, &src, dim)?; Try / catch
match t.scatter_set(&idx, &src, dim) {
Ok(()) => (),
Err(e) if e.to_string().contains("share their storage") => {
let src = src.copy()?;
t.scatter_set(&idx, &src, dim)?;
}
Err(e) => return Err(e.into()),
} Prevention
- Remember that views (slice, transpose, reshape) share storage; copy before in-place ops.
- Prefer out-of-place scatter when in doubt.
- For errors from this API prefer scatter_add_set semantics carefully; note the message text mentions slice_set erroneously.
When it happens
Trigger: Calling t.scatter_set(&indexes, &src, dim) where src was derived from t via views/reshapes/slices sharing storage (e.g. src = t.clone() at view level or src = t.i(..)).
Common situations: Chained in-place updates on tensors that alias each other; writing updated values back into a tensor using a slice of itself as source.
Related errors
AI-assisted analysis of huggingface/candle@d5fee525bf (2026-09-02).
Data as JSON: /api/errors/ffe493c6a049823d.
Report an issue: GitHub.