{"record":{"id":"6e6c3a54d79b53ea","repo":"zeroclaw-labs/zeroclaw","slug":"whatsapp-interactive-list-capped-at-10-sections-g","errorCode":null,"errorMessage":"WhatsApp interactive list capped at 10 sections (got {})","messagePattern":"WhatsApp interactive list capped at 10 sections \\(got (.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-channels/src/whatsapp.rs","lineNumber":615,"sourceCode":"    /// Send an interactive list message (more than 3 options, up to 10\n    /// rows per section, up to 10 sections per Meta's limits). `sections`\n    /// each carry a section title + rows. Each row's `id` round-trips\n    /// through the inbound `interactive.list_reply.id` as `[choice]<id>`.\n    ///\n    /// `button_text` is the button label that opens the list (Meta limits\n    /// to 20 chars).\n    pub async fn send_interactive_list(\n        &self,\n        recipient: &str,\n        body_text: &str,\n        button_text: &str,\n        sections: &[InteractiveListSection],\n    ) -> anyhow::Result<()> {\n        if sections.is_empty() {\n            anyhow::bail!(\"WhatsApp interactive list requires at least one section\");\n        }\n        if sections.len() > 10 {\n            anyhow::bail!(\n                \"WhatsApp interactive list capped at 10 sections (got {})\",\n                sections.len()\n            );\n        }\n        for s in sections {\n            if s.rows.len() > 10 {\n                anyhow::bail!(\n                    \"WhatsApp interactive list section '{}' capped at 10 rows (got {})\",\n                    s.title,\n                    s.rows.len()\n                );\n            }\n        }\n        let url = format!(\n            \"https://graph.facebook.com/v18.0/{}/messages\",\n            self.endpoint_id\n        );\n        ensure_https(&url)?;","sourceCodeStart":597,"sourceCodeEnd":633,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-channels/src/whatsapp.rs#L597-L633","documentation":"Meta's interactive list messages allow at most 10 sections per message; `send_interactive_list` enforces this client-side and reports the offending count. No HTTP request is made. Related but distinct from the per-section row cap (10 rows, see the section-row error).","triggerScenarios":"Calling `send_interactive_list` with a `sections` slice of 11 or more entries — e.g. one section per category when a catalog has 15 categories, or chunking options into sections smaller than 10 rows so the section count balloons.","commonSituations":"Auto-generated catalogs or menus with many categories; chunking with a small chunk size (e.g. `chunks(5)` over 60 options yields 12 sections); assuming the library paginates for you — only `send_choice` chunks automatically, and it also caps at 10 sections.","solutions":["Merge or re-chunk sections until there are at most 10 (use chunks of up to 10 rows each, which supports 100 options in 10 sections).","Split the content across multiple list messages.","For flat option lists, call `send_choice(recipient, prompt, &options)` — it chunks 10 rows per section automatically and stays within both caps up to 100 options."],"exampleFix":"// before: 15 category sections -> bails at the 10-section cap\nchannel.send_interactive_list(to, \"Catalog:\", \"Browse\", &by_category).await?;\n\n// after: re-chunk into at most 10 sections of at most 10 rows\nlet sections: Vec<_> = all_rows\n    .chunks(10)\n    .enumerate()\n    .map(|(i, c)| InteractiveListSection {\n        title: format!(\"Items {}-{}\", i * 10 + 1, i * 10 + c.len()),\n        rows: c.to_vec(),\n    })\n    .collect();\nchannel.send_interactive_list(to, \"Catalog:\", \"Browse\", &sections).await?;","handlingStrategy":"validation","validationCode":"const MAX_SECTIONS: usize = 10;\nif sections.len() > MAX_SECTIONS {\n    anyhow::bail!(\"{} sections exceeds WhatsApp's {}-section cap\", sections.len(), MAX_SECTIONS);\n}\nchannel.send_interactive_list(recipient, body, button_text, &sections).await","typeGuard":"fn within_section_cap(sections: &[InteractiveListSection]) -> bool {\n    sections.len() <= 10\n}","tryCatchPattern":null,"preventionTips":["Chunk options with `chunks(10)` so section count stays <= ceil(n/10) <= 10 for n <= 100.","Cap categories at the data layer when mapping one category to one section.","Remember the total shape: 10 sections x 10 rows = 100 options maximum."],"tags":["whatsapp","interactive-list","api-limits","validation","rust"],"backgroundTag":"api-limit-exceeded","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}