{"record":{"id":"fed325a2b18a0503","repo":"zeroclaw-labs/zeroclaw","slug":"matrix-selected-single-message-progress-edit-exce","errorCode":null,"errorMessage":"matrix: selected single-message progress edit exceeds configured message_max_bytes","messagePattern":"matrix: selected single-message progress edit exceeds configured message_max_bytes","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-channels/src/matrix.rs","lineNumber":3670,"sourceCode":"            ));\n            let event = room\n                .make_edit_event(event_id, EditedContent::RoomMessage(new_content))\n                .await\n                .map_err(|e| {\n                    ::zeroclaw_log::record!(\n                        ERROR,\n                        ::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Fail)\n                            .with_outcome(::zeroclaw_log::EventOutcome::Failure)\n                            .with_attrs(::serde_json::json!({\"error\": format!(\"{}\", e)})),\n                        \"make_edit_event failed\"\n                    );\n                    anyhow::Error::msg(format!(\"make_edit_event failed: {e}\"))\n                })?;\n            if let Some(max_bytes) = message_max_bytes {\n                let actual =\n                    serde_json::to_vec(&event).map_or(usize::MAX, |serialized| serialized.len());\n                if actual > max_bytes {\n                    anyhow::bail!(\n                        \"matrix: selected single-message progress edit exceeds configured message_max_bytes\"\n                    );\n                }\n            }\n            event\n        };\n        room.send(edit_event).await?;\n        Ok(candidate)\n    }\n\n    pub(super) async fn redact(\n        client: &Client,\n        room_id: &str,\n        event_id: &OwnedEventId,\n        reason: Option<String>,\n    ) -> Result<()> {\n        let room = client\n            .get_room(&room_id.parse::<OwnedRoomId>()?)","sourceCodeStart":3652,"sourceCodeEnd":3688,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-channels/src/matrix.rs#L3652-L3688","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: the in-place edit grows without bound\nlet text = format!(\"{previous}\\n{new_line}\");\nedit(&client, &room_id, &event_id, &text, message_max_bytes).await?;\n\n// after: keep the edit body under the budget (envelope overhead included)\nlet text = if previous.len() + new_line.len() + 1 > BODY_BUDGET {\n    new_line.clone() // restart the summary instead of overflowing the cap\n} else {\n    format!(\"{previous}\\n{new_line}\")\n};\nedit(&client, &room_id, &event_id, &text, message_max_bytes).await?;","handlingStrategy":"validation","validationCode":"const EVENT_ENVELOPE_OVERHEAD: usize = 1024; // measure once for your homeserver\n\nfn edit_fits_budget(text: &str, max_bytes: Option<usize>) -> bool {\n    match max_bytes {\n        None => true,\n        Some(max) => text.len() + EVENT_ENVELOPE_OVERHEAD <= max,\n    }\n}\n\nassert!(edit_fits_budget(&next_progress_text, config.message_max_bytes));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["matrix","message-size","single-message","edit","config"],"backgroundTag":"message-size-limit-exceeded","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}