{"record":{"id":"c57066b7a18a440d","repo":"risingwavelabs/risingwave","slug":"invalid-sign","errorCode":null,"errorMessage":"Invalid sign: {}","messagePattern":"Invalid sign: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/stream/src/executor/approx_percentile/global_state.rs","lineNumber":109,"sourceCode":"            .iter_with_prefix(&[Datum::None; 0], &bounds, PrefetchOptions::default())\n            .await?\n        {\n            let row = keyed_row?.into_owned_row();\n            let sign = row.datum_at(0).unwrap().into_int16();\n            let bucket_id = row.datum_at(1).unwrap().into_int32();\n            let count = row.datum_at(2).unwrap().into_int64();\n            match sign {\n                -1 => {\n                    self.cache.neg_buckets.insert(bucket_id, count as i64);\n                }\n                0 => {\n                    self.cache.zeros = count as i64;\n                }\n                1 => {\n                    self.cache.pos_buckets.insert(bucket_id, count as i64);\n                }\n                _ => {\n                    bail!(\"Invalid sign: {}\", sign);\n                }\n            }\n        }\n        Ok(())\n    }\n\n    async fn get_row_count_state(&self) -> StreamExecutorResult<Option<OwnedRow>> {\n        self.count_state_table.get_row(&[Datum::None; 0]).await\n    }\n\n    fn decode_row_count(row_count_state: &Option<OwnedRow>) -> StreamExecutorResult<i64> {\n        if let Some(row) = row_count_state.as_ref() {\n            let Some(datum) = row.datum_at(0) else {\n                bail!(\"Invalid row count state: {:?}\", row)\n            };\n            Ok(datum.into_int64())\n        } else {\n            Ok(0)","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/stream/src/executor/approx_percentile/global_state.rs#L91-L127","documentation":"The approx_percentile global aggregator decodes per-bucket counts from its state table, where each row carries a `sign` column (0 for negative buckets, 1 for positive buckets, and zeros handled separately). `refill_cache` bails when it reads a sign value other than the expected 0/1 set, meaning the persisted bucket state is corrupt or from an incompatible schema version.","triggerScenarios":"Restoring approx_percentile aggregation state from a state table whose rows contain an unexpected `sign` value (e.g. state written by different code version or manually corrupted), during `init` when refilling the in-memory cache from persisted buckets.","commonSituations":"RisingWave version upgrade with changed state-table schema, state store corruption, or recovery from a checkpoint written by a buggy build.","solutions":["Identify the materialized view containing approx_percentile and recreate it (DROP and re-CREATE) to rebuild clean state.","Check whether the cluster was upgraded between writing and reading this state; restore from a backup taken with the same version if possible.","Enable debug logging on the affected table ID and inspect the state table rows to confirm corruption; report it if it's a writer bug.","Upgrade to the latest patch release in case the writer side has been fixed."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Avoid approx_percentile state written by mixed RisingWave versions; rebuild aggregations after upgrades.","Monitor state store health/checksums to catch corruption early.","Keep backups of critical materialized view state before cluster upgrades."],"tags":["streaming","state-corruption","approx-percentile","recovery"],"backgroundTag":"invalid-enum-value","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"}