{"record":{"id":"4406588168ed0504","repo":"quickwit-oss/quickwit","slug":"storekey-encode-ordinal","errorCode":null,"errorMessage":"storekey encode ordinal: {}","messagePattern":"storekey encode ordinal: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"quickwit/quickwit-parquet-engine/src/sorted_series/mod.rs","lineNumber":292,"sourceCode":"///\n/// Layout: `storekey(ordinal: u8) || storekey(value)`. For descending\n/// columns the *value* bytes are inverted in place (NOT the ordinal\n/// byte) so memcmp on the composite reverses the value's lex order\n/// while ordinals stay in declared order. Caller skips this function\n/// entirely for null columns — the next column's higher ordinal byte\n/// then appears in this column's place, which gives nulls-last\n/// ordering without a sentinel marker (matches the writer's\n/// `nulls_first=false` convention).\npub(crate) fn append_prefix_col_to_key<T>(\n    buf: &mut Vec<u8>,\n    ordinal: u8,\n    value: &T,\n    descending: bool,\n) -> Result<()>\nwhere\n    T: ?Sized + storekey::Encode,\n{\n    storekey::encode(&mut *buf, &ordinal).map_err(|e| anyhow!(\"storekey encode ordinal: {}\", e))?;\n    let value_start = buf.len();\n    storekey::encode(&mut *buf, value).map_err(|e| anyhow!(\"storekey encode value: {}\", e))?;\n    if descending {\n        invert_bytes(&mut buf[value_start..]);\n    }\n    Ok(())\n}\n\n/// Bitwise-NOT a byte slice in place, inverting the sort order for\n/// descending columns in the composite key. This is the standard\n/// ordered-code technique: if ascending bytes A < B, then !A > !B,\n/// so memcmp on the inverted bytes gives descending order.\nfn invert_bytes(bytes: &mut [u8]) {\n    for byte in bytes.iter_mut() {\n        *byte = !*byte;\n    }\n}\n","sourceCodeStart":274,"sourceCodeEnd":310,"githubUrl":"https://github.com/quickwit-oss/quickwit/blob/a39730c5cdcd1a4fe798403737ae293999ea21f8/quickwit/quickwit-parquet-engine/src/sorted_series/mod.rs#L274-L310","documentation":"append_prefix_col_to_key serializes a row-key entry as (ordinal, value) into a byte buffer using the storekey crate. This error is returned when storekey fails to encode the ordinal portion (the u64 row ordinal) before the value bytes are appended. It wraps the underlying storekey::encode error message.","triggerScenarios":"Calling encode_row_key/encode_byte_array_value/encode_prefix_col_value when the underlying storekey encoder rejects the ordinal type — e.g. buffer write failures or an unsized/mis-typed T violates the storekey::Encode bound at runtime.","commonSituations":"Building row keys for sorted series during parquet-engine index writes; a corrupted or oversized output buffer, or a storekey codec version mismatch between encoder and reader.","solutions":["Read the inner storekey error in the message to identify which Encode impl failed","Ensure the buffer passed in is a valid, writable Vec<u8> (caller passes &mut *buf)","Verify the ordinal type used matches the expected fixed-width integer supported by storekey","Check storekey version compatibility between writer and reader code paths"],"exampleFix":"// before: opaque wrap\nstorekey::encode(&mut *buf, &ordinal).map_err(|e| anyhow!(\"storekey encode ordinal: {}\", e))?;\n// after: add context about buffer state\nstorekey::encode(&mut *buf, &ordinal).map_err(|e| anyhow!(\"storekey encode ordinal (buf_len={}): {}\", buf.len(), e))?;","handlingStrategy":"try-catch","validationCode":"assert!(buf.capacity() >= buf.len() + size_of::<u64>() + value.len());","typeGuard":null,"tryCatchPattern":"match encode_row_key(&mut buf, ordinal, value, descending) {\n    Err(e) if e.to_string().contains(\"storekey encode ordinal\") => { /* log + inspect buffer/type */ }\n    Err(e) => return Err(e),\n    Ok(()) => {},\n}","preventionTips":["Keep ordinal types as fixed-width integers supported by storekey","Wrap serialization in unit tests round-tripping encode/decode","Pin storekey versions across the workspace"],"tags":["serialization","rust","storekey","row-key"],"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-17T15:17:12.973Z"}