quickwit-oss/quickwit · error

field does not exist: {}

Error message

field does not exist: {}

What it means

While planning a TermSetQuery, the query builder warms up term dictionaries for each field named in terms_per_field; if a field name does not resolve in the index schema (even with dynamic-field fallback), the query cannot be executed and is rejected.

Source

Thrown at quickwit/quickwit-doc-mapper/src/query_builder.rs:258

    fn new(schema: &'a Schema) -> Self {
        ExtractTermSetFields {
            term_dict_fields_to_warm_up: HashSet::new(),
            schema,
        }
    }
}

impl<'a> QueryAstVisitor<'a> for ExtractTermSetFields<'_> {
    type Err = anyhow::Error;

    fn visit_term_set(&mut self, term_set_query: &'a TermSetQuery) -> anyhow::Result<()> {
        for field in term_set_query.terms_per_field.keys() {
            if let Some((field, _field_entry, _path)) =
                find_field_or_hit_dynamic(field, self.schema)
            {
                self.term_dict_fields_to_warm_up.insert(field);
            } else {
                anyhow::bail!("field does not exist: {}", field);
            }
        }
        Ok(())
    }
}

fn extract_term_set_query_fields(
    query_ast: &QueryAst,
    schema: &Schema,
) -> anyhow::Result<HashSet<Field>> {
    let mut visitor = ExtractTermSetFields::new(schema);
    visitor.visit(query_ast)?;
    Ok(visitor.term_dict_fields_to_warm_up)
}

/// Converts a `prefix` term into the equivalent term range.
///
/// The resulting range is `[prefix, next_prefix)`, that is:

View on GitHub (pinned to a39730c5cd)

Solutions

  1. Fix the field name in the query to match a field in the index schema (check with the describe-index API).
  2. Add the field to the index mapping and re-index or use dynamic mode.
  3. Verify the query targets the correct index whose schema actually contains the field.

Example fix

// before
curl -X POST .../search -d '{"query": "foo:[a TO b]", ...}' with term_set on missing field
// after
{"term_set": {"field": "message", "terms": ["error", "warn"]}}  // 'message' exists in schema
Defensive patterns

Strategy: try-catch

Validate before calling

// before querying
let schema = client.index(index_id).await?.descriptor().doc_mapping; // or describe-index
if !schema_field_names.contains(&field_name) {
    return Err(format!("field `{field_name}` not in index schema"));
}

Type guard

fn field_exists(schema_fields: &[String], field: &str) -> bool {
    schema_fields.iter().any(|f| f == field)
}

Try / catch

match resp {
    Err(e) if e.to_string().starts_with("field does not exist") => {
        // correct the field name or refresh schema and retry once
    }
    other => other?,
}

Prevention

When it happens

Trigger: Executing a search with a term set query `{"term_set": {"field": "foo", "terms": [...]}}` where `foo` is not in the index schema and is not matched by dynamic mapping, via visit_term_set in QueryBuilder.

Common situations: Typos in field names in search queries; querying an index whose schema changed (field renamed/removed); clients reusing query templates across indexes with different schemas; relying on a dynamic field that was never ingested so it is not in the schema.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of quickwit-oss/quickwit@a39730c5cd (2026-09-08). Data as JSON: /api/errors/2be5cb6d840ef357. Report an issue: GitHub.