huggingface/candle · error
not a f32 {v:?}
Error message
not a f32 {v:?} What it means
This error is thrown by Value::to_f32 in candle's GGUF reader when you ask a GGUF metadata value to be an f32 but the Value enum actually holds a different variant (e.g. String, U32, Array). GGUF metadata values are tagged unions, so conversion only succeeds when the variant matches exactly; candle bails instead of coercing. The {v:?} in the message prints the actual variant that was found.
Source
Thrown at candle-core/src/quantized/gguf_file.rs:287
Self::U8(v) => Ok(*v as u64),
Self::U16(v) => Ok(*v as u64),
Self::U32(v) => Ok(*v as u64),
Self::Bool(v) => Ok(*v as u64),
v => crate::bail!("not a u64 or upcastable to u64 {v:?}"),
}
}
pub fn to_i64(&self) -> Result<i64> {
match self {
Self::I64(v) => Ok(*v),
v => crate::bail!("not a i64 {v:?}"),
}
}
pub fn to_f32(&self) -> Result<f32> {
match self {
Self::F32(v) => Ok(*v),
v => crate::bail!("not a f32 {v:?}"),
}
}
pub fn to_f64(&self) -> Result<f64> {
match self {
Self::F64(v) => Ok(*v),
v => crate::bail!("not a f64 {v:?}"),
}
}
pub fn to_bool(&self) -> Result<bool> {
match self {
Self::Bool(v) => Ok(*v),
v => crate::bail!("not a bool {v:?}"),
}
}
pub fn to_vec(&self) -> Result<&Vec<Value>> {View on GitHub (pinned to d5fee525bf)
Solutions
- Call .to_u32()/.to_u64() instead if the field was written as an integer (most GGUF numeric metadata is u32).
- Inspect the error's {v:?} payload to see the real variant and use the matching accessor (to_f64, to_string, to_vec, ...).
- Match on the Value enum directly and handle multiple variants instead of using a fixed accessor.
- Fix the GGUF writing side to emit ValueType::F32 if the field genuinely should be a float.
Example fix
// before
let emb_len = value.to_f32()?;
// after
let emb_len = match value {
gguf_file::Value::U32(v) => v as f32,
gguf_file::Value::F32(v) => v,
other => candle_core::bail!("unexpected embedding_length {other:?}"),
}; Defensive patterns
Strategy: type-guard
Validate before calling
fn is_f32(v: &gguf_file::Value) -> bool { matches!(v, gguf_file::Value::F32(_)) }
if !is_f32(value) { bail!("expected f32 metadata, got {value:?}"); } Type guard
fn as_f32(v: &gguf_file::Value) -> Option<f32> {
if let gguf_file::Value::F32(x) = v { Some(*x) } else { None }
} Try / catch
let f = match value.to_f32() {
Ok(f) => f,
Err(e) => { eprintln!("gguf f32 field mismatch: {e}"); return fallback_default; }
}; Prevention
- Match on the Value enum instead of calling fixed accessors when field types may vary
- Remember GGUF numeric metadata is usually u32/u64, not f32
- Log the Debug form of the Value on mismatch to identify the real type
- Validate key types once after Content::read, before business logic
When it happens
Trigger: Calling .to_f32() on a Value read from a GGUF file whose metadata entry is not ValueType::F32, e.g. a model's 'embedding_length' stored as u32 (the common case) or a string field like 'general.architecture'.
Common situations: Hand-parsing GGUF headers with gguf_file::Content::read and assuming numeric fields are f32 when GGUF spec defaults them to u32/u64; reading a file produced by a converter that wrote f64 or u32; typos in field names picking up the wrong metadata entry.
Related errors
- not a f64 {v:?}
- not a bool {v:?}
- not a vec {v:?}
- not a string {v:?}
- multiple value-types in the same array {value_type:?}
AI-assisted analysis of huggingface/candle@d5fee525bf (2026-09-02).
Data as JSON: /api/errors/8e0b5f4ff1dd3681.
Report an issue: GitHub.