huggingface/candle · error
not a string {v:?}
Error message
not a string {v:?} What it means
Value::to_string throws this when the GGUF metadata value is not the String variant. GGUF strings are a distinct tagged type (with their own length prefix), and candle will not stringify other variants implicitly. The Debug form of the found value appears in the message.
Source
Thrown at candle-core/src/quantized/gguf_file.rs:315
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>> {
match self {
Self::Array(v) => Ok(v),
v => crate::bail!("not a vec {v:?}"),
}
}
pub fn to_string(&self) -> Result<&String> {
match self {
Self::String(v) => Ok(v),
v => crate::bail!("not a string {v:?}"),
}
}
fn read<R: std::io::Read + std::io::Seek>(
reader: &mut R,
value_type: ValueType,
magic: &VersionedMagic,
depth: usize,
file_size: u64,
) -> Result<Self> {
if depth > GGUF_MAX_VALUE_DEPTH {
crate::bail!("gguf: value nesting depth exceeds max {GGUF_MAX_VALUE_DEPTH}")
}
let v = match value_type {
ValueType::U8 => Self::U8(reader.read_u8()?),
ValueType::I8 => Self::I8(reader.read_i8()?),
ValueType::U16 => Self::U16(reader.read_u16::<LittleEndian>()?),
ValueType::I16 => Self::I16(reader.read_i16::<LittleEndian>()?),View on GitHub (pinned to d5fee525bf)
Solutions
- Read the actual variant from the {v:?} output and use its accessor (to_u32, to_vec, ...).
- Verify the metadata key name — a misspelled or renamed key may resolve to a differently typed entry.
- Match on the Value enum and convert manually (e.g. format integer variants if a string display is wanted).
- Fix the GGUF producer to write the field with ValueType::String.
Example fix
// before
let arch = value.to_string()?;
// after
let arch = match value {
gguf_file::Value::String(s) => s.as_str(),
other => candle_core::bail!("general.architecture is not a string: {other:?}"),
}; Defensive patterns
Strategy: type-guard
Validate before calling
fn is_string(v: &gguf_file::Value) -> bool { matches!(v, gguf_file::Value::String(_)) }
if !is_string(value) { bail!("expected string metadata, got {value:?}"); } Type guard
fn as_str(v: &gguf_file::Value) -> Option<&str> {
if let gguf_file::Value::String(s) = v { Some(s.as_str()) } else { None }
} Try / catch
let s = match value.to_string() {
Ok(s) => s.clone(),
Err(e) => { eprintln!("not a string: {e}"); return Err(e.into()); }
}; Prevention
- Don't confuse Rust's ToString with GGUF's to_string (which asserts the String variant)
- Print the Debug value on mismatch to discover the actual variant
- Lock metadata key names against the GGUF spec for the architecture
- Fail fast with a clear message instead of silently coercing types
When it happens
Trigger: Calling .to_string() on a metadata entry stored as U8/U32/I64/Array etc., e.g. expecting 'general.architecture' to be a string but grabbing a numeric or array-valued key instead.
Common situations: Wrong metadata key lookup returning a numeric field; assuming byte-array tokens are strings when they are Arrays of u32; using to_string() on Value out of habit because Rust's ToString exists.
Related errors
- not a f32 {v:?}
- not a f64 {v:?}
- not a bool {v:?}
- not a vec {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/1bd55f3fee3936d6.
Report an issue: GitHub.