{"record":{"id":"869a3da3868fd27b","repo":"risingwavelabs/risingwave","slug":"invalid-variant-encoding","errorCode":null,"errorMessage":"Invalid variant encoding","messagePattern":"Invalid variant encoding","errorType":"error_code","errorClass":"ValueEncodingError","httpStatus":null,"severity":"error","filePath":"src/common/src/util/value_encoding/error.rs","lineNumber":33,"sourceCode":"use thiserror::Error;\n\n#[derive(Error, Debug)]\npub enum ValueEncodingError {\n    #[error(\"Invalid bool value encoding: {0}\")]\n    InvalidBoolEncoding(u8),\n    #[error(\"Invalid UTF8 value encoding: {0}\")]\n    InvalidUtf8(#[from] std::string::FromUtf8Error),\n    #[error(\"Invalid Date value encoding: days: {0}\")]\n    InvalidDateEncoding(i32),\n    #[error(\"invalid Timestamp value encoding: secs: {0} nsecs: {1}\")]\n    InvalidTimestampEncoding(i64, u32),\n    #[error(\"invalid Time value encoding: secs: {0} nano: {1}\")]\n    InvalidTimeEncoding(u32, u32),\n    #[error(\"Invalid null tag value encoding: {0}\")]\n    InvalidTagEncoding(u8),\n    #[error(\"Invalid jsonb encoding\")]\n    InvalidJsonbEncoding,\n    #[error(\"Invalid variant encoding\")]\n    InvalidVariantEncoding,\n    #[error(\"Invalid struct encoding: {0}\")]\n    InvalidStructEncoding(\n        #[source]\n        #[backtrace]\n        crate::array::ArrayError,\n    ),\n    #[error(\"Invalid list encoding: {0}\")]\n    InvalidListEncoding(\n        #[source]\n        #[backtrace]\n        crate::array::ArrayError,\n    ),\n    #[error(\"Invalid flag: {0:b}\")]\n    InvalidFlag(u8),\n    #[error(\"Invalid vector item: {0} {1}\")]\n    InvalidVectorItem(f32, String),\n}","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/common/src/util/value_encoding/error.rs#L15-L51","documentation":"ValueEncodingError::InvalidVariantEncoding is thrown when a Variant column's stored bytes cannot be deserialized into a VariantVal. In deserialize_value for DataType::Variant (src/common/src/util/value_encoding/mod.rs:386-389), VariantVal::value_deserialize returns None for malformed payloads and the code raises this error. It signals that the persisted variant bytes are corrupt or written in an incompatible format.","triggerScenarios":"Calling deserialize_value/deserialize_datum on DataType::Variant where the length-prefixed bytea payload is not valid variant binary encoding (truncation, foreign writer, format-version mismatch).","commonSituations":"Reading rows written by a cluster version with a different variant layout; data ingested/persisted by an external tool; corrupted storage bytes; hand-crafted bytes passed to the deserializer in tests.","solutions":["Ensure the payload was serialized with VariantVal::value_serialize from a matching RisingWave version","Align reader/writer versions to eliminate format skew","Rewrite the affected rows (re-ingest or refresh the materialization)","Validate variant payloads before persistence"],"exampleFix":"// before\nlet val = VariantVal::value_deserialize(bytes).ok_or(ValueEncodingError::InvalidVariantEncoding)?;\n// after: check length prefix against actual slice length first\nlet (len, rest) = (u32::from_le_bytes(bytes[..4].try_into().unwrap()) as usize, &bytes[4..]);\nassert_eq!(len, rest.len(), \"truncated variant payload\");\nlet val = VariantVal::value_deserialize(rest).ok_or(ValueEncodingError::InvalidVariantEncoding)?;","handlingStrategy":"try-catch","validationCode":"fn valid_variant_payload(bytes: &[u8]) -> bool {\n    !bytes.is_empty() && VariantVal::value_deserialize(bytes).is_some()\n}","typeGuard":"fn is_decodable_variant(bytes: &[u8]) -> Option<VariantVal> {\n    VariantVal::value_deserialize(bytes)\n}","tryCatchPattern":"match deserialize_datum(&DataType::Variant, data) {\n    Ok(Some(datum)) => { /* use datum */ }\n    Ok(None) => { /* NULL datum */ }\n    Err(ValueEncodingError::InvalidVariantEncoding) => {\n        tracing::error!(\"corrupt variant bytes; skip or rewrite row\");\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Use VariantVal::value_serialize exclusively for persisting variants","Verify length prefix matches payload length before decoding","Add encode/decode round-trip tests for variant columns","Align RisingWave versions across writer and reader nodes"],"tags":["rust","value-encoding","variant","deserialization","risingwave"],"backgroundTag":"json-decode-failed","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}