quickwit-oss/quickwit · error

input {} has index_uid '{}', expected '{}'

Error message

input {} has index_uid '{}', expected '{}'

What it means

merge_parquet_split_metadata enforces that all input splits belong to the same index. This bail fires when input i's `index_uid` differs from `inputs[0].index_uid`. A merge can only produce output metadata for one index, so cross-index inputs indicate a broken compaction-scope selection.

Source

Thrown at quickwit/quickwit-parquet-engine/src/merge/metadata_aggregation.rs:73

) -> Result<ParquetSplitMetadata> {
    if inputs.is_empty() {
        bail!("merge_parquet_split_metadata requires at least one input split");
    }

    let first = &inputs[0];

    // Validate invariant fields: all inputs must agree on these.
    for (i, input) in inputs.iter().enumerate().skip(1) {
        if input.kind != first.kind {
            bail!(
                "input {} has kind {:?}, expected {:?}",
                i,
                input.kind,
                first.kind
            );
        }
        if input.index_uid != first.index_uid {
            bail!(
                "input {} has index_uid '{}', expected '{}'",
                i,
                input.index_uid,
                first.index_uid
            );
        }
        if input.partition_id != first.partition_id {
            bail!(
                "input {} has partition_id {}, expected {}",
                i,
                input.partition_id,
                first.partition_id
            );
        }
        if input.sort_fields != first.sort_fields {
            bail!(
                "input {} has sort_fields '{}', expected '{}'",
                i,

View on GitHub (pinned to a39730c5cd)

Solutions

  1. Fix the merge task grouping to include index_uid in the scope key so only same-index splits are merged together.
  2. Check for stale splits from a deleted/recreated index and purge them from the merge candidate set.
  3. Verify the split metadata source (task queue / metastore fetch) filters by the current index_uid.
  4. In tests, use a constructor helper that stamps one shared index_uid on every input.

Example fix

// before
candidates.retain(|s| s.partition_id == task.partition_id);
// after
candidates.retain(|s| s.index_uid == task.index_uid && s.partition_id == task.partition_id);
Defensive patterns

Strategy: validation

Validate before calling

fn single_index(inputs: &[ParquetSplitMetadata]) -> bool {
    inputs.iter().all(|s| s.index_uid == inputs[0].index_uid)
}

Type guard

fn same_index_uid(inputs: &[ParquetSplitMetadata]) -> Option<&str> {
    let uid = &inputs.first()?.index_uid;
    inputs.iter().all(|s| &s.index_uid == uid).then_some(uid.as_str())
}

Try / catch

match merge_parquet_split_metadata(&inputs, &output, mixed) {
    Err(e) if e.to_string().contains("index_uid") => {
        error!("cross-index merge task detected: {e:#}; dropping task and alerting");
        // quarantine the task, do not retry as-is
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling merge_parquet_split_metadata with inputs whose ParquetSplitMetadata.index_uid values differ — e.g. the merge planner grouped tasks by partition_id but not index_uid, or split metadata was deserialized from the wrong index task queue.

Common situations: Control-plane bug assigning splits from two indexes to one indexing task; index deletion/re-creation reusing a partition id while stale splits from the old index remain; test fixtures with copy-pasted index_uids.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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