{"record":{"id":"bfa16d58bcc848c7","repo":"linera-io/linera-protocol","slug":"count-exceeds-u32-bfa16d","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/reentrant_collection_view.rs","lineNumber":2353,"sourceCode":"\n    #[async_graphql::Object(cache_control(no_cache), name_type)]\n    impl<K, V> ReentrantCollectionView<V::Context, K, V>\n    where\n        K: async_graphql::InputType\n            + async_graphql::OutputType\n            + serde::ser::Serialize\n            + serde::de::DeserializeOwned\n            + std::fmt::Debug,\n        V: View + async_graphql::OutputType,\n    {\n        async fn keys(&self) -> Result<Vec<K>, async_graphql::Error> {\n            Ok(self.indices().await?)\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(\n            &self,\n            key: K,\n        ) -> Result<Entry<K, ReadGuardedView<V>>, async_graphql::Error> {\n            let value = self\n                .try_load_entry(&key)\n                .await?\n                .ok_or_else(|| missing_key_error(&key))?;\n            Ok(Entry { value, key })\n        }\n\n        async fn entries(\n            &self,\n            input: Option<MapInput<K>>,\n        ) -> Result<Vec<Entry<K, ReadGuardedView<V>>>, async_graphql::Error> {\n            let keys = if let Some(keys) = input","sourceCodeStart":2335,"sourceCodeEnd":2371,"githubUrl":"https://github.com/linera-io/linera-protocol/blob/6c226ddcb332ef55118dc8d0aafbd093d5420899/linera-views/src/views/reentrant_collection_view.rs#L2335-L2371","documentation":"The GraphQL schema generated for `ReentrantCustomCollectionView` exposes a derived `count` field typed u32. The entry count is a `usize` from `iterative_count`; when it exceeds `u32::MAX` the narrowing conversion fails with 'count exceeds u32'. Only collections beyond ~4.29 billion entries can trigger it — it is a schema-limit guard.","triggerScenarios":"Querying `count` on a ReentrantCustomCollectionView (views containing other views as values) holding more than 4,294,967,295 entries.","commonSituations":"Long-lived applications storing one nested view per operation with no pruning; adversarial/stress tests deliberately exceeding the u32 boundary.","solutions":["Page via `keys`/`entries` and aggregate client-side instead of calling `count` on giant views.","Bound growth by pruning or sharding entries across multiple views.","Maintain an explicit u64 counter in application state.","Request an upstream change widening the GraphQL field if >2^32 entries is a real requirement."],"exampleFix":"# before\nquery { app { state { records { count } } } }  # 'count exceeds u32'\n\n# after\nquery { app { state { records { keys(count: 1000) } } } }  # paginate; expose recordsTotal as u64 in the app","handlingStrategy":"fallback","validationCode":"# page a single key first\nquery { app { state { records { keys(count: 1) } } } }","typeGuard":null,"tryCatchPattern":"try { return await gql.query('query { app { state { records { count } } } }'); } catch (e) { if (/count exceeds u32/i.test(e.message)) { return tallyViaPagedKeys('records'); } throw e; }","preventionTips":["Prune nested-view collections aggressively; each entry is itself a view.","Expose an explicit counter in application state.","Page with keys/entries rather than counting."],"tags":["graphql","views","count","u32-overflow","reentrant-collection-view"],"backgroundTag":"integer-overflow","analyzedSha":"6c226ddcb332ef55118dc8d0aafbd093d5420899","analyzedAt":"2026-08-22T22:49:09.787Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}