zeroclaw-labs/zeroclaw · error
WhatsApp interactive list capped at 10 sections (got {})
Error message
WhatsApp interactive list capped at 10 sections (got {}) What it means
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).
Source
Thrown at crates/zeroclaw-channels/src/whatsapp.rs:615
/// Send an interactive list message (more than 3 options, up to 10
/// rows per section, up to 10 sections per Meta's limits). `sections`
/// each carry a section title + rows. Each row's `id` round-trips
/// through the inbound `interactive.list_reply.id` as `[choice]<id>`.
///
/// `button_text` is the button label that opens the list (Meta limits
/// to 20 chars).
pub async fn send_interactive_list(
&self,
recipient: &str,
body_text: &str,
button_text: &str,
sections: &[InteractiveListSection],
) -> anyhow::Result<()> {
if sections.is_empty() {
anyhow::bail!("WhatsApp interactive list requires at least one section");
}
if sections.len() > 10 {
anyhow::bail!(
"WhatsApp interactive list capped at 10 sections (got {})",
sections.len()
);
}
for s in sections {
if s.rows.len() > 10 {
anyhow::bail!(
"WhatsApp interactive list section '{}' capped at 10 rows (got {})",
s.title,
s.rows.len()
);
}
}
let url = format!(
"https://graph.facebook.com/v18.0/{}/messages",
self.endpoint_id
);
ensure_https(&url)?;View on GitHub (pinned to 88bb9c8533)
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.
Example fix
// before: 15 category sections -> bails at the 10-section cap
channel.send_interactive_list(to, "Catalog:", "Browse", &by_category).await?;
// after: re-chunk into at most 10 sections of at most 10 rows
let sections: Vec<_> = all_rows
.chunks(10)
.enumerate()
.map(|(i, c)| InteractiveListSection {
title: format!("Items {}-{}", i * 10 + 1, i * 10 + c.len()),
rows: c.to_vec(),
})
.collect();
channel.send_interactive_list(to, "Catalog:", "Browse", §ions).await?; Defensive patterns
Strategy: validation
Validate before calling
const MAX_SECTIONS: usize = 10;
if sections.len() > MAX_SECTIONS {
anyhow::bail!("{} sections exceeds WhatsApp's {}-section cap", sections.len(), MAX_SECTIONS);
}
channel.send_interactive_list(recipient, body, button_text, §ions).await Type guard
fn within_section_cap(sections: &[InteractiveListSection]) -> bool {
sections.len() <= 10
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- WhatsApp interactive list section '{}' capped at 10 rows (go
- WhatsApp send_choice: {} options exceeds list cap ({}); spli
- WhatsApp interactive list requires at least one section
- WhatsApp interactive buttons require 1..=3 options (got {});
- WhatsApp location marker must be `lat,lng[,name[,address]]`
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/6e6c3a54d79b53ea.
Report an issue: GitHub.