huggingface/candle · error
mergeable_ranks is not an object
Error message
mergeable_ranks is not an object
What it means
This error is thrown by Encoding::from_json in candle-transformers' metavoice model when the JSON tokenizer file's "mergeable_ranks" field exists but is not a JSON object (e.g. it is a string, array, number, or null). from_json expects a BPE-style mapping of byte sequences (hex keys) to u32 ranks, so it validates the field's type before iterating. It is a data-format validation failure, not a runtime bug.
Source
Thrown at candle-transformers/src/models/metavoice.rs:220
None => candle::bail!("pat_str field is not a string"),
Some(pat_str) => fancy_regex::Regex::new(pat_str).map_err(E::wrap)?,
},
};
let offset = match json.get("offset") {
None => candle::bail!("json object has no offset field"),
Some(offset) => match offset.as_u64() {
None => candle::bail!("offset field is not a positive int"),
Some(offset) => offset as usize,
},
};
let mut ranks = HashMap::new();
for id in 0u8..=255 {
ranks.insert(vec![id], id as u32);
}
let mergeable_ranks = match json.get("mergeable_ranks") {
None => candle::bail!("json object has no mergeable_ranks field"),
Some(mr) => match mr.as_object() {
None => candle::bail!("mergeable_ranks is not an object"),
Some(mr) => mr,
},
};
for (key, value) in mergeable_ranks.iter() {
let value = match value.as_u64() {
None => candle::bail!("mergeable_ranks '{key}' is not a u64"),
Some(value) => value as u32,
};
if value < 256 {
continue;
}
// No escaping for other keys.
let key = key.as_bytes().to_vec();
ranks.insert(key, value);
}
Ok(Self {
re,
end_of_text,View on GitHub (pinned to d5fee525bf)
Solutions
- Inspect the tokenizer JSON and make "mergeable_ranks" a JSON object whose keys are hex byte strings and values are u64/u32 rank numbers
- Regenerate or re-download the tokenizer file from the official MetaVoice model repository to match the expected format
- Confirm you are passing the right tokenizer file (not a vocab.json or merges file from a different format) to from_json
Example fix
// before (invalid)
{"mergeable_ranks": "[{"AA==": 256}]"}
// after (valid)
{"mergeable_ranks": {"AA==": 256, "AQ==": 257}} Defensive patterns
Strategy: validation
Validate before calling
let mr = json.get("mergeable_ranks")
.ok_or("missing mergeable_ranks")?;
if !mr.is_object() {
return Err("mergeable_ranks must be a JSON object");
} Type guard
fn is_object(v: &serde_json::Value) -> bool {
matches!(v, serde_json::Value::Object(_))
} Try / catch
let enc = Encoding::from_json(&json)
.map_err(|e| format!("bad tokenizer json: {e}"))?; Prevention
- Validate tokenizer JSON structure (mergeable_ranks is an object of int ranks) before loading
- Re-download tokenizer files from the official model repo rather than converting formats by hand
- Add a JSON schema check in your pipeline for tokenizer files
When it happens
Trigger: Calling Encoding::from_json (or the metavoice tokenizer loading path that wraps it) with a JSON file where "mergeable_ranks" is present but typed incorrectly — e.g. a serialized array of pairs, a JSON string containing the ranks, or null.
Common situations: Using a tokenizer.json from a different model family whose mergeable_ranks is stored in a different format; hand-editing or truncating the tokenizer JSON; downloading a corrupted or incomplete tokenizer file; using a JSON dump produced by a script that stringified the ranks.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- mergeable_ranks '{key}' is not a u64
- {} is a dummy type and cannot be constructed
- {} is a dummy type and cannot be converted
- {} is a dummy type and cannot be converted to scalar
- {} is a dummy type and does not support storage
AI-assisted analysis of huggingface/candle@d5fee525bf (2026-09-02).
Data as JSON: /api/errors/6af22dbb85ccc323.
Report an issue: GitHub.