{"record":{"id":"9f79bdb1b9fa8ee2","repo":"zeroclaw-labs/zeroclaw","slug":"whatsapp-interactive-list-section-capped-at-1","errorCode":null,"errorMessage":"WhatsApp interactive list section '{}' capped at 10 rows (got {})","messagePattern":"WhatsApp interactive list section '(.+?)' capped at 10 rows \\(got (.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-channels/src/whatsapp.rs","lineNumber":622,"sourceCode":"    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)?;\n        let to = recipient.strip_prefix('+').unwrap_or(recipient);\n        let action_sections: Vec<serde_json::Value> = sections\n            .iter()\n            .map(|s| {\n                let rows: Vec<serde_json::Value> = s\n                    .rows\n                    .iter()","sourceCodeStart":604,"sourceCodeEnd":640,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-channels/src/whatsapp.rs#L604-L640","documentation":"Each section of a WhatsApp interactive list may hold at most 10 rows; `send_interactive_list` validates every section up front and names the first offending section's title and row count. This mirrors Meta's list-message contract and fails before any HTTP call. The total message cap is 100 rows (10 sections x 10 rows).","triggerScenarios":"Passing any `InteractiveListSection` whose `rows.len() > 10` — e.g. a single 'All items' section containing 25 rows, or uneven chunking that leaves a long tail in one section.","commonSituations":"Flat item lists dumped into one section; forgetting that the per-section cap (10) is far smaller than the total cap (100); manual section construction that bypasses the chunking `send_choice` does.","solutions":["Chunk rows into sections of at most 10 (`options.chunks(10)`), the same way `send_choice` does.","Trim the list or paginate interactively (e.g. a final 'More' row that triggers the next page).","For flat option lists, prefer `send_choice`, which chunks automatically."],"exampleFix":"// before\nlet sections = vec![InteractiveListSection {\n    title: \"All\".into(),\n    rows: all_25_rows, // > 10 rows -> bails\n}];\n\n// after\nlet sections: Vec<_> = all_rows\n    .chunks(10)\n    .enumerate()\n    .map(|(i, c)| InteractiveListSection {\n        title: format!(\"Options {}-{}\", i * 10 + 1, i * 10 + c.len()),\n        rows: c.to_vec(),\n    })\n    .collect();","handlingStrategy":"validation","validationCode":"for s in &sections {\n    anyhow::ensure!(s.rows.len() <= 10, \"section '{}' has {} rows (max 10)\", s.title, s.rows.len());\n}\nchannel.send_interactive_list(recipient, body, button_text, &sections).await","typeGuard":"fn rows_within_cap(section: &InteractiveListSection) -> bool {\n    section.rows.len() <= 10\n}","tryCatchPattern":null,"preventionTips":["Always build sections with `chunks(10)` rather than pushing rows into one accumulator section.","Add a unit test asserting every generated section has 1..=10 rows.","Watch pagination code: a 'last page' section built from a remainder slice still must respect the cap."],"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"}