quickwit-oss/quickwit · error · anyhow::Error

`record`, `tokenizer`, and `fieldnorms` parameters are allow

Error message

`record`, `tokenizer`, and `fieldnorms` parameters are allowed only if indexed is true

What it means

For text field mappings, indexing options `record` (frequency/position storage), `tokenizer`, and `fieldnorms` only make sense when the field is indexed. When building the text FieldMappingEntry with indexed=false, specifying any of these is contradictory and the builder rejects the mapping.

Source

Thrown at quickwit/quickwit-doc-mapper/src/doc_mapper/field_mapping_entry.rs:331

    pub fieldnorms: bool,
}

impl TextIndexingOptions {
    fn from_parts_text(
        indexed: bool,
        tokenizer: Option<QuickwitTextTokenizer>,
        record: Option<IndexRecordOption>,
        fieldnorms: bool,
    ) -> anyhow::Result<Option<Self>> {
        if indexed {
            Ok(Some(TextIndexingOptions {
                tokenizer: tokenizer.unwrap_or_default(),
                record: record.unwrap_or(IndexRecordOption::Basic),
                fieldnorms,
            }))
        } else {
            if tokenizer.is_some() || record.is_some() || fieldnorms {
                bail!(
                    "`record`, `tokenizer`, and `fieldnorms` parameters are allowed only if \
                     indexed is true"
                )
            }
            Ok(None)
        }
    }

    fn from_parts_json(
        indexed: bool,
        tokenizer: Option<QuickwitTextTokenizer>,
        record: Option<IndexRecordOption>,
    ) -> anyhow::Result<Option<Self>> {
        if indexed {
            Ok(Some(TextIndexingOptions {
                tokenizer: tokenizer.unwrap_or_else(QuickwitTextTokenizer::raw),
                record: record.unwrap_or(IndexRecordOption::Basic),
                fieldnorms: false,

View on GitHub (pinned to a39730c5cd)

Solutions

  1. Remove `tokenizer`, `record`, and `fieldnorms` from the field mapping when `indexed: false`.
  2. If you need those options, set `indexed: true` instead.
  3. If the field is only meant for storage/fast retrieval, switch to appropriate options (e.g. keep indexed:false and only fast/stored flags).

Example fix

// before
{name: "notes", type: "text", indexed: false, tokenizer: "raw"}
// after
{name: "notes", type: "text", indexed: false}
Defensive patterns

Strategy: validation

Validate before calling

fn text_mapping_is_consistent(f: &serde_json::Value) -> bool {
    if f.get("indexed").and_then(|v| v.as_bool()) == Some(false) {
        !(f.get("tokenizer").is_some()
            || f.get("record").is_some()
            || f.get("fieldnorms").is_some())
    } else { true }
}

Try / catch

match create_index_result {
    Err(e) if e.to_string().contains("parameters are allowed only if indexed is true") => {
        eprintln!("Remove tokenizer/record/fieldnorms from fields with indexed:false");
    }
    other => other?,
}

Prevention

When it happens

Trigger: Defining a field mapping JSON like `{type: "text", indexed: false, tokenizer: "raw"}` (or with `record`/`fieldnorms` set) — the from_parts_text constructor bails because indexing parameters accompany indexed:false.

Common situations: Users copying a text field mapping and just flipping `indexed: false` while leaving tokenizer/record options; storing-only text fields configured with search options; templates that always emit tokenizer settings.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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