quickwit-oss/tantivy · error · io::Error

Invalid value type id: {num}

Error message

Invalid value type id: {num}

What it means

DefaultDocument's Deserialize impl reads a u8 type id and transmutes it to ValueType, but only for ids 0..=13 which are the valid discriminants. Any other byte cannot be a ValueType, so the unsafe transmute is guarded and this InvalidData error is returned instead of producing a bogus enum value.

Source

Thrown at src/schema/document/default_document.rs:573

    Object = 11,
    /// Pre-tokenized str type,
    Array = 12,
    /// Opaque payload of a plugin-defined custom field.
    Custom = 13,
}

impl BinarySerializable for ValueType {
    fn serialize<W: Write + ?Sized>(&self, writer: &mut W) -> io::Result<()> {
        (*self as u8).serialize(writer)?;
        Ok(())
    }

    fn deserialize<R: Read>(reader: &mut R) -> io::Result<Self> {
        let num = u8::deserialize(reader)?;
        let type_id = if (0..=13).contains(&num) {
            unsafe { std::mem::transmute::<u8, ValueType>(num) }
        } else {
            return Err(io::Error::new(
                io::ErrorKind::InvalidData,
                format!("Invalid value type id: {num}"),
            ));
        };
        Ok(type_id)
    }
}

impl<'a, V: Value<'a>> From<&ReferenceValue<'a, V>> for ValueType {
    fn from(value: &ReferenceValue<'a, V>) -> Self {
        match value {
            ReferenceValue::Leaf(leaf) => leaf.into(),
            ReferenceValue::Array(_) => ValueType::Array,
            ReferenceValue::Object(_) => ValueType::Object,
        }
    }
}
impl<'a> From<&ReferenceValueLeaf<'a>> for ValueType {

View on GitHub (pinned to b5d8deb80c)

Solutions

  1. Upgrade tantivy to the writer's version so new type ids are understood
  2. Re-index or restore the corrupted document/file from a backup
  3. When crafting serialized Values in tests, use a valid type id in 0..=13 (prefer the enum's serialized form, not a raw number)
  4. Enable checksummed storage or validate files to catch corruption earlier

Example fix

// before (hand-crafted fixture)
bytes.push(42u8); // invalid type id -> "Invalid value type id: 42"
// after
bytes.push(ValueType::Str as u8); // a valid, in-range type id
Defensive patterns

Strategy: type-guard

Validate before calling

fn is_valid_value_type_id(b: u8) -> bool { b <= 13 }

Type guard

fn valid_value_type_id(b: u8) -> Option<u8> {
    (b <= 13).then_some(b)
}

Try / catch

match deserialize_result {
    Err(e) if e.to_string().contains("Invalid value type id") => {
        eprintln!("corrupt or newer-format document; restore/re-index");
    }
    Err(e) => return Err(e),
    Ok(v) => v,
}

Prevention

When it happens

Trigger: deserialize on a document stream whose ValueType tag byte is > 13: corrupted stored/quickwit documents, data written by a newer version with additional ValueTypes, or hand-built byte fixtures with a wrong tag.

Common situations: Cross-version index reads (newer writer, older reader); bit corruption in stored documents; tests or fixtures encoding Value types with incorrect numeric ids.

Related errors


AI-assisted analysis of quickwit-oss/tantivy@b5d8deb80c (2026-09-05). Data as JSON: /api/errors/4cbc64f470d6e1f0. Report an issue: GitHub.