zeroclaw-labs/zeroclaw · error · anyhow::Error
matrix: selected single-message progress edit exceeds config
Error message
matrix: selected single-message progress edit exceeds configured message_max_bytes
What it means
In single-message progress mode the bot edits one message in place; edit() builds the replacement event via make_edit_event, serializes it, and enforces message_max_bytes. Unlike the threaded-reply path there is no iterative shrinking here - a single edit whose serialized event exceeds the budget aborts immediately. The usual driver is progress text that grows across edits (append-style summaries) until serialization crosses the cap.
Source
Thrown at crates/zeroclaw-channels/src/matrix.rs:3670
));
let event = room
.make_edit_event(event_id, EditedContent::RoomMessage(new_content))
.await
.map_err(|e| {
::zeroclaw_log::record!(
ERROR,
::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Fail)
.with_outcome(::zeroclaw_log::EventOutcome::Failure)
.with_attrs(::serde_json::json!({"error": format!("{}", e)})),
"make_edit_event failed"
);
anyhow::Error::msg(format!("make_edit_event failed: {e}"))
})?;
if let Some(max_bytes) = message_max_bytes {
let actual =
serde_json::to_vec(&event).map_or(usize::MAX, |serialized| serialized.len());
if actual > max_bytes {
anyhow::bail!(
"matrix: selected single-message progress edit exceeds configured message_max_bytes"
);
}
}
event
};
room.send(edit_event).await?;
Ok(candidate)
}
pub(super) async fn redact(
client: &Client,
room_id: &str,
event_id: &OwnedEventId,
reason: Option<String>,
) -> Result<()> {
let room = client
.get_room(&room_id.parse::<OwnedRoomId>()?)View on GitHub (pinned to 88bb9c8533)
Solutions
- Raise channels.matrix.message_max_bytes above the largest expected edit.
- Bound the progress text in agent code: cap the rendered summary and rotate or drop old lines instead of growing forever.
- If long content is expected, switch the room to multi-message mode, which splits output instead of failing one big edit.
Example fix
// before: the in-place edit grows without bound
let text = format!("{previous}\n{new_line}");
edit(&client, &room_id, &event_id, &text, message_max_bytes).await?;
// after: keep the edit body under the budget (envelope overhead included)
let text = if previous.len() + new_line.len() + 1 > BODY_BUDGET {
new_line.clone() // restart the summary instead of overflowing the cap
} else {
format!("{previous}\n{new_line}")
};
edit(&client, &room_id, &event_id, &text, message_max_bytes).await?; Defensive patterns
Strategy: validation
Validate before calling
const EVENT_ENVELOPE_OVERHEAD: usize = 1024; // measure once for your homeserver
fn edit_fits_budget(text: &str, max_bytes: Option<usize>) -> bool {
match max_bytes {
None => true,
Some(max) => text.len() + EVENT_ENVELOPE_OVERHEAD <= max,
}
}
assert!(edit_fits_budget(&next_progress_text, config.message_max_bytes)); Prevention
- Cap generated progress summaries to message_max_bytes minus envelope overhead before invoking the edit.
- Trim from the head (oldest lines) as the summary grows so single-message edits stay bounded.
- Measure the real serialized floor once per deployment and encode it as the overhead constant.
When it happens
Trigger: single_message mode with a configured message_max_bytes where make_edit_event produces an event larger than the cap - the accumulated progress text plus event envelope and the edited-content relation outgrew the budget.
Common situations: Progress messages appending a line per step until they exceed the cap; tightening message_max_bytes after deployment; Markdown inflation (bullet lists, code fences) as task output gets complex; long tool output quoted into the single message.
Related errors
- matrix: configured message_max_bytes cannot contain a thread
- matrix: single-message draft state unavailable
- matrix: {reason} Cannot auto-recover because channels.matrix
- matrix login requires either access_token or user_id+passwor
- matrix: configured channels.matrix.user-id ({configured}) do
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/fed325a2b18a0503.
Report an issue: GitHub.