{"record":{"id":"9808da1ecac19230","repo":"Hmbown/CodeWhale","slug":"exceeded-the-page-catalogue-limit","errorCode":null,"errorMessage":"{} exceeded the {}-page catalogue limit","messagePattern":"(.+?) exceeded the (.+?)-page catalogue limit","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/mcp.rs","lineNumber":1491,"sourceCode":"        Self {\n            method,\n            pages: 0,\n            items: 0,\n            bytes: 0,\n            seen_cursors: HashSet::new(),\n        }\n    }\n\n    fn observe_page(\n        &mut self,\n        result: &serde_json::Value,\n        item_count: usize,\n    ) -> Result<Option<String>> {\n        self.pages = self.pages.saturating_add(1);\n        self.items = self.items.saturating_add(item_count);\n        self.bytes = self.bytes.saturating_add(serde_json::to_vec(result)?.len());\n        if self.pages > MAX_MCP_CATALOG_PAGES {\n            anyhow::bail!(\n                \"{} exceeded the {}-page catalogue limit\",\n                self.method,\n                MAX_MCP_CATALOG_PAGES\n            );\n        }\n        if self.items > MAX_MCP_CATALOG_ITEMS {\n            anyhow::bail!(\n                \"{} exceeded the {}-item catalogue limit\",\n                self.method,\n                MAX_MCP_CATALOG_ITEMS\n            );\n        }\n        if self.bytes > MAX_MCP_CATALOG_BYTES {\n            anyhow::bail!(\n                \"{} exceeded the {}-byte aggregate catalogue limit\",\n                self.method,\n                MAX_MCP_CATALOG_BYTES\n            );","sourceCodeStart":1473,"sourceCodeEnd":1509,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/mcp.rs#L1473-L1509","documentation":"MCP catalogue discovery responses are capped at MAX_MCP_CATALOG_PAGES pages. This budget-tracker method counts pages as results stream in and bails once the page count exceeds the configured maximum. It protects the client from a malicious or broken server that streams unbounded pagination (resource exhaustion, prompt/context flooding).","triggerScenarios":"The discovery accumulator's track method increments self.pages on every result page; it bails when pages > MAX_MCP_CATALOG_PAGES — i.e. the server returned more paginated responses than allowed for the method.","commonSituations":"A server with an enormous tool catalogue paginating hundreds of results; a misbehaving or compromised server that never stops returning pages; a very low catalogue limit configured for an intentionally tiny plugin environment.","solutions":["Reduce the number of tools the MCP server exposes so it fits within the page limit","Configure/raise MAX_MCP_CATALOG_PAGES if your server legitimately needs a larger catalogue and you trust it","Investigate the server if pagination seems unbounded — endless pages can indicate a bug or attack"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"# Estimate catalogue size before connecting: ask the server how many pages it advertises,\n# or sample tools/list and extrapolate. There is no pre-call API — guard the call instead.","typeGuard":null,"tryCatchPattern":"match discovery_result {\n    Err(e) if e.to_string().contains(\"-page catalogue limit\") => {\n        eprintln!(\"Server catalogue too large for configured limits; reduce exposed tools or raise MAX_MCP_CATALOG_PAGES.\");\n    }\n    Ok(catalogue) => use_catalogue(catalogue),\n    other => other?,\n}","preventionTips":["Keep MCP servers small and focused so catalogues fit within default limits","If you operate the server, cap its advertised tools to what clients allow","Watch for the page cap in logs — hitting it may signal a runaway/compromised server"],"tags":["mcp","limit","pagination","resource-exhaustion"],"backgroundTag":"payload-too-large","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}