quickwit-oss/tantivy · error
Exist query without a field isn't allowed
Error message
Exist query without a field isn't allowed
What it means
This is a panic (expect) inside UserInputLeaf's field-setting transformation: when transforming an Exists leaf with a field, the field Option is expected to be Some. An Exists query without a field is considered a programmer error by the query-grammar layer, so it panics rather than returning Result. It fires because the caller forgot to set a default field before this transformation.
Source
Thrown at query-grammar/src/user_input_ast.rs:51
pub(crate) fn set_field(self, field: Option<String>) -> Self {
match self {
UserInputLeaf::Literal(mut literal) => {
literal.field_name = field;
UserInputLeaf::Literal(literal)
}
UserInputLeaf::All => UserInputLeaf::All,
UserInputLeaf::Range {
field: _,
lower,
upper,
} => UserInputLeaf::Range {
field,
lower,
upper,
},
UserInputLeaf::Set { field: _, elements } => UserInputLeaf::Set { field, elements },
UserInputLeaf::Exists { field: _ } => UserInputLeaf::Exists {
field: field.expect("Exist query without a field isn't allowed"),
},
UserInputLeaf::Regex { field: _, pattern } => UserInputLeaf::Regex { field, pattern },
}
}
pub(crate) fn set_default_field(&mut self, default_field: String) {
match self {
UserInputLeaf::Literal(literal) if literal.field_name.is_none() => {
literal.field_name = Some(default_field)
}
UserInputLeaf::All => {
*self = UserInputLeaf::Exists {
field: default_field,
}
}
UserInputLeaf::Range { field, .. } if field.is_none() => *field = Some(default_field),
UserInputLeaf::Set { field, .. } if field.is_none() => *field = Some(default_field),
UserInputLeaf::Regex { field, .. } if field.is_none() => *field = Some(default_field),View on GitHub (pinned to b5d8deb80c)
Solutions
- Ensure a default field is set (set_default_field) before transforming/normalizing the AST.
- Construct Exists leaves with a field always present, or validate the AST before transforming it.
- If you control parsing, return a user-facing parse/validation error instead of reaching the expect: check field.is_some() beforehand.
- Never let end-user input reach this transform without the default-field configuration step.
Example fix
// before
let leaf = UserInputLeaf::Exists { field: None };
leaf.with_field(...) // panics
// after
if leaf_field.is_some() {
leaf.with_field(...)
} else {
return Err(QueryParserError::FieldDoesNotExist("_exists requires a field"));
} Defensive patterns
Strategy: validation
Validate before calling
// Validate before transforming the AST
fn ensure_fields_set(ast: &UserInputAst) -> Result<(), &'static str> {
if let UserInputAst::Leaf(leaf) = ast {
if let UserInputLeaf::Exists { field } = leaf {
if field.is_none() { return Err("_exists leaf requires a field"); }
}
}
Ok(())
} Type guard
fn has_field(leaf: &UserInputLeaf) -> bool {
!matches!(leaf, UserInputLeaf::Exists { field: None })
} Try / catch
// This is a panic, not a Result: prevent it, and if wrapping, isolate the transform
let result = std::panic::catch_unwind(|| {
ast.with_field(default_field)
}); Prevention
- Always call set_default_field before AST normalization
- Never forward raw user input without default-field configuration
- Prefer constructing Exists leaves with explicit fields
- Add unit tests for Exists leaves without fields
When it happens
Trigger: Calling the field-assigning method on a UserInputAst containing UserInputLeaf::Exists with field == None, i.e. after parsing something like _exists: without having set a default field via set_default_field or equivalent.
Common situations: Building query ASTs programmatically and forgetting to assign the default field; query parsers that pass user input straight through where the default field was never configured; writing tests/transforms over parsed leaves.
Related errors
- unknown compressor id {id:?}
- actual doc store version: {doc_store_version}, max_supported
- FastFieldsPlugin is a built-in; use FastFieldsPluginWriter::
- All columns re required to be numerical
- Invalid op metadata byte
AI-assisted analysis of quickwit-oss/tantivy@b5d8deb80c (2026-09-05).
Data as JSON: /api/errors/b21d0d7ec7c7e2ab.
Report an issue: GitHub.