huggingface/candle · error

shape mismatch on {path}: {shape:?} <> {tensor_shape:?}

Error message

shape mismatch on {path}: {shape:?} <> {tensor_shape:?}

What it means

VarMap::get looks up a variable by path and validates that the requested shape matches the stored tensor's shape. If a variable already exists under that path but with a different shape than requested, the library bails instead of silently reusing or reshaping it. This protects callers from accidentally sharing a cached variable that has incompatible dimensions.

Source

Thrown at candle-nn/src/var_map.rs:108

        }
        Ok(())
    }

    /// Retrieve or add a new variable.
    pub fn get<S: Into<Shape>>(
        &self,
        shape: S,
        path: &str,
        init: crate::Init,
        dtype: DType,
        device: &Device,
    ) -> Result<Tensor> {
        let shape = shape.into();
        let mut tensor_data = self.data.lock().unwrap();
        if let Some(tensor) = tensor_data.get(path) {
            let tensor_shape = tensor.shape();
            if &shape != tensor_shape {
                candle::bail!("shape mismatch on {path}: {shape:?} <> {tensor_shape:?}")
            }
            return Ok(tensor.as_tensor().clone());
        }
        let var = init.var(shape, dtype, device)?;
        let tensor = var.as_tensor().clone();
        tensor_data.insert(path.to_string(), var);
        Ok(tensor)
    }

    pub fn data(&self) -> &Mutex<HashMap<String, Var>> {
        &self.data
    }
}

View on GitHub (pinned to d5fee525bf)

Solutions

  1. Make the requested shape match the shape the variable was originally created with (print tensor_shape from the error to compare).
  2. If shapes intentionally differ, use a different path/name for the new variable or clear the VarMap (create a fresh one) before rebuilding.
  3. When loading a safetensors/var-builder map, verify the model config used to compute shapes matches the checkpoint's config.
  4. If a reshape is what you want, fetch the existing tensor and reshape it explicitly rather than calling get with a mismatched shape.

Example fix

// before
let w = var_map.get(( vocab, hidden ), DType::F32, "h.model.weight", init)?; // vocab changed to 32000
// after
let w = var_map.get(( 32000, hidden ), DType::F32, "h.model.weight", init)?; // match stored shape
Defensive patterns

Strategy: validation

Validate before calling

let stored = var_map.data.lock().unwrap().get(path).map(|t| t.shape().clone());
if let Some(s) = &stored {
    assert_eq!(s, &shape, "VarMap '{path}' shape {s:?} != requested {shape:?}");
}

Type guard

fn shape_matches(stored: &candle::Shape, requested: &[usize]) -> bool {
    stored.dims() == requested
}

Try / catch

match var_map.get(shape, dtype, path, init) {
    Ok(t) => t,
    Err(e) if e.to_string().contains("shape mismatch") => {
        // rebuild with fresh VarMap or corrected shape
        let mut fresh = VarMap::new();
        fresh.get(shape, dtype, path, init)?
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling VarMap::get (directly or via var/get helpers) with a shape argument that differs from the shape the variable was first created with under the same path; typically across two model builds in one process where layer sizes changed (e.g. different vocab size, hidden size, or batch dims).

Common situations: Re-running a model-construction function twice in one process with a different config; loading pretrained weights whose shapes don't match the model definition; typos causing two different layers to collide on the same path.

Related errors


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