{"record":{"id":"0d98bfccbf1f4faf","repo":"linera-io/linera-protocol","slug":"count-exceeds-u32-0d98bf","errorCode":null,"errorMessage":"count exceeds u32","messagePattern":"count exceeds u32","errorType":"http","errorClass":"async_graphql::Error","httpStatus":null,"severity":"error","filePath":"linera-views/src/views/map_view.rs","lineNumber":2282,"sourceCode":"            + Clone\n            + Send\n            + Sync\n            + 'static,\n    {\n        async fn keys(&self, count: Option<usize>) -> Result<Vec<I>, async_graphql::Error> {\n            let indices = self.indices().await?;\n            let it = indices.iter().cloned();\n            Ok(if let Some(count) = count {\n                it.take(count).collect()\n            } else {\n                it.collect()\n            })\n        }\n\n        #[graphql(derived(name = \"count\"))]\n        async fn count_(&self) -> Result<u32, async_graphql::Error> {\n            let count = self.iterative_count().await?;\n            u32::try_from(count).map_err(|_| async_graphql::Error::new(\"count exceeds u32\"))\n        }\n\n        async fn entry(&self, key: I) -> Result<Entry<I, Option<V>>, async_graphql::Error> {\n            Ok(Entry {\n                value: self.get(&key).await?,\n                key,\n            })\n        }\n\n        async fn entries(\n            &self,\n            input: Option<MapInput<I>>,\n        ) -> Result<Vec<Entry<I, Option<V>>>, async_graphql::Error> {\n            let keys = input\n                .and_then(|input| input.filters)\n                .and_then(|filters| filters.keys);\n            let keys = if let Some(keys) = keys {\n                keys","sourceCodeStart":2264,"sourceCodeEnd":2300,"githubUrl":"https://github.com/linera-io/linera-protocol/blob/6c226ddcb332ef55118dc8d0aafbd093d5420899/linera-views/src/views/map_view.rs#L2264-L2300","documentation":"The GraphQL schema generated for `MapView` exposes a derived `count` field typed u32. The true number of keys is a `usize` produced by `iterative_count`; if it exceeds `u32::MAX` the `u32::try_from` fails and the resolver returns 'count exceeds u32'. This can only happen with over four billion map entries — an overflow guard, rarely seen in practice.","triggerScenarios":"Querying `count` on a MapView that has accumulated more than 4,294,967,295 keys (e.g. per-account records in a very long-lived application).","commonSituations":"Unbounded per-operation map growth without pruning; synthetic tests filling a map past the boundary.","solutions":["Use `keys(count: n)` / `entries(input: { filters: { keys: [...] } })` for paginated or targeted access instead of `count`.","Prune or archive old map entries so the collection stays representable.","Expose an explicit u64 counter in the application state rather than the derived `count`.","Upstream, widen the field type if >2^32 entries is genuinely needed."],"exampleFix":"# before\nquery { app { state { balances { count } } } }  # fails past u32::MAX keys\n\n# after\nquery { app { state { balances { entry(key: \"<account>\") { value } } } } }  # targeted lookup; track total separately","handlingStrategy":"fallback","validationCode":"# targeted entry lookup avoids the count entirely\nquery { app { state { balances { entry(key: \"<account>\") { value } } } } }","typeGuard":null,"tryCatchPattern":"try { return await gql.query('query { app { state { balances { count } } } }'); } catch (e) { if (/count exceeds u32/i.test(e.message)) { return tallyViaPagedKeys('balances'); } throw e; }","preventionTips":["Use entry(key) for point lookups instead of counting the whole map.","Expire or aggregate historical map entries.","Track totals in an explicit u64 field."],"tags":["graphql","views","count","u32-overflow","map-view"],"backgroundTag":"integer-overflow","analyzedSha":"6c226ddcb332ef55118dc8d0aafbd093d5420899","analyzedAt":"2026-08-22T22:49:09.787Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}