{"record":{"id":"33085c2ac47516a6","repo":"quickwit-oss/quickwit","slug":"sort-schema-does-not-contain-timeseries-id-sorte","errorCode":null,"errorMessage":"sort schema does not contain timeseries_id — sorted_series key requires it as the guaranteed discriminator for series identity","messagePattern":"sort schema does not contain timeseries_id — sorted_series key requires it as the guaranteed discriminator for series identity","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"quickwit/quickwit-parquet-engine/src/sorted_series/mod.rs","lineNumber":210,"sourceCode":"            });\n            break;\n        }\n        if crate::sort_fields::is_timestamp_column_name(&col.name) {\n            break;\n        }\n        let is_descending = col.sort_direction\n            == quickwit_proto::sortschema::SortColumnDirection::SortDirectionDescending as i32;\n        if let Ok(idx) = batch_schema.index_of(&col.name) {\n            tag_columns.push(KeyColumn {\n                ordinal: ordinal as u8,\n                batch_idx: idx,\n                descending: is_descending,\n            });\n        }\n    }\n\n    let ts_id_column = ts_id_column.ok_or_else(|| {\n        anyhow!(\n            \"sort schema does not contain timeseries_id — sorted_series key requires it as the \\\n             guaranteed discriminator for series identity\"\n        )\n    })?;\n\n    Ok(ResolvedKeySchema {\n        tag_columns,\n        ts_id_column,\n    })\n}\n\n/// Encode a single row's sorted series key into `buf`.\n///\n/// For ascending columns, storekey bytes are written directly — memcmp\n/// gives ascending order. For descending columns, the storekey bytes for\n/// that column's (ordinal, value) pair are bitwise-NOTed so that ascending\n/// memcmp on the composite key gives the correct descending order.\n/// This is the standard ordered-code technique (see Google's OrderedCode).","sourceCodeStart":192,"sourceCodeEnd":228,"githubUrl":"https://github.com/quickwit-oss/quickwit/blob/a39730c5cdcd1a4fe798403737ae293999ea21f8/quickwit/quickwit-parquet-engine/src/sorted_series/mod.rs#L192-L228","documentation":"resolve_key_columns walks the sort schema and requires timeseries_id to be present in it, since sorted_series keys need the series-identity hash as a tiebreaker. If the configured sort schema never lists a column named timeseries_id (the loop ends without setting ts_id_column), this error is raised.","triggerScenarios":"compute_sorted_series_column invoked with a SortSchema proto whose column list omits timeseries_id — a misconfigured or truncated sort schema, or a schema built dynamically that stopped before adding the hash column.","commonSituations":"Hand-written index config with a custom sort schema missing timeseries_id; schema generated from user-supplied sort fields only; a proto built from older config formats that did not include it.","solutions":["Add a timeseries_id entry to the sort schema configuration before the first timestamp column.","Validate the SortSchema at config-load time so bad schemas fail early rather than at merge time.","If the schema comes from a template/older format, migrate it to include the timeseries_id discriminator."],"exampleFix":"// before: sort_schema columns = [service, metric_name, timestamp]\n// after: sort_schema columns = [service, metric_name, timeseries_id, timestamp]\n// (timeseries_id must appear before any timestamp column)","handlingStrategy":"validation","validationCode":"if !sort_schema.column.iter().any(|c| c.name == \"timeseries_id\") {\n    return Err(anyhow!(\"invalid sort schema: timeseries_id is required\"));\n}\n","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"sort schema does not contain timeseries_id\") => {\n        // fix config and reload: sort_schema.columns.insert(idx, timeseries_id_col)\n        return Err(e.context(\"fix the index sort-schema configuration\"));\n    }\n    other => other,\n}\n","preventionTips":["Validate sort schemas at index-creation time to require timeseries_id before any timestamp column.","Centralize sort-schema construction in one helper that always appends the timeseries_id entry.","Add a config linter/test covering generated and user-supplied sort schemas."],"tags":["sorted-series","config","sort-schema","merge"],"backgroundTag":"missing-required-config-field","analyzedSha":"a39730c5cdcd1a4fe798403737ae293999ea21f8","analyzedAt":"2026-09-08T13:19:37.784Z","contentChangedAt":"2026-09-08T13:19:37.784Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}