{"record":{"id":"0fb0c756100b41a7","repo":"quickwit-oss/quickwit","slug":"input-has-window-expected","errorCode":null,"errorMessage":"input {} has window {:?}, expected {:?}","messagePattern":"input (.+?) has window (.+?), expected (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"quickwit/quickwit-parquet-engine/src/merge/metadata_aggregation.rs","lineNumber":97,"sourceCode":"        }\n        if input.partition_id != first.partition_id {\n            bail!(\n                \"input {} has partition_id {}, expected {}\",\n                i,\n                input.partition_id,\n                first.partition_id\n            );\n        }\n        if input.sort_fields != first.sort_fields {\n            bail!(\n                \"input {} has sort_fields '{}', expected '{}'\",\n                i,\n                input.sort_fields,\n                first.sort_fields\n            );\n        }\n        if input.window != first.window {\n            bail!(\n                \"input {} has window {:?}, expected {:?}\",\n                i,\n                input.window,\n                first.window\n            );\n        }\n        if !mixed_prefix_ok && input.rg_partition_prefix_len != first.rg_partition_prefix_len {\n            bail!(\n                \"input {} has rg_partition_prefix_len {}, expected {} — splits with different \\\n                 prefix lengths must not appear in the same regular merge (legacy-promotion \\\n                 operations bypass this check)\",\n                i,\n                input.rg_partition_prefix_len,\n                first.rg_partition_prefix_len\n            );\n        }\n    }\n","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/quickwit-oss/quickwit/blob/a39730c5cdcd1a4fe798403737ae293999ea21f8/quickwit/quickwit-parquet-engine/src/merge/metadata_aggregation.rs#L79-L115","documentation":"merge_parquet_split_metadata requires all input splits to share the same `window` (time-bucketing window). This bail fires when input i's window differs from inputs[0]'s. The output split inherits a single window value; merging splits bucketed to different windows would produce inconsistent time-range/partitioning metadata.","triggerScenarios":"Calling merge_parquet_split_metadata with splits whose Optional window values differ — e.g. compaction selecting a time-windowed split together with a non-windowed (legacy) split, or splits created before/after the index's window configuration changed.","commonSituations":"Index window duration changed at runtime; a legacy promotion or migration left old non-windowed splits alongside new windowed ones; merge planner groups only by index_uid/partition and forgets the window dimension.","solutions":["Include the window value in the merge-scope grouping key so only same-window splits are merged.","Handle legacy non-windowed splits via the dedicated legacy-promotion path (mixed_prefix_ok / promotion op) rather than a regular merge.","Pin or version the index's window configuration to avoid mixed-window eras, or run a re-bucketing migration.","Log the offending split's id/window alongside the error to identify where the mixed batch came from."],"exampleFix":"// before\nlet key = (split.index_uid.clone(), split.partition_id);\n// after\nlet key = (split.index_uid.clone(), split.partition_id, split.window);","handlingStrategy":"validation","validationCode":"fn window_consistent(inputs: &[ParquetSplitMetadata]) -> bool {\n    inputs.iter().all(|s| s.window == inputs[0].window)\n}","typeGuard":"fn same_window(inputs: &[ParquetSplitMetadata]) -> Option<Option<Window>> {\n    let w = inputs.first()?.window;\n    inputs.iter().all(|s| s.window == w).then_some(w)\n}","tryCatchPattern":"match merge_parquet_split_metadata(&inputs, &output, mixed) {\n    Err(e) if e.to_string().contains(\"window\") => {\n        warn!(\"mixed-window merge rejected: {e:#}; regrouping by window\");\n        return regroup_by_window_and_retry(inputs);\n    }\n    other => other?,\n}","preventionTips":["Add window to the merge-grouping key.","Avoid changing the index window configuration without migrating existing splits.","Route legacy non-windowed splits through a dedicated promotion path, never a regular merge."],"tags":["rust","merge","time-window","invariant-violation"],"backgroundTag":"internal-invariant-violation","analyzedSha":"a39730c5cdcd1a4fe798403737ae293999ea21f8","analyzedAt":"2026-09-08T13:19:37.784Z","contentChangedAt":"2026-09-08T13:19:37.784Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}