{"record":{"id":"5021282d2d72fbb6","repo":"zeroclaw-labs/zeroclaw","slug":"matrix-corruption-recovery-looped-aborting-to-a","errorCode":null,"errorMessage":"matrix: corruption recovery looped — aborting to avoid an infinite restart cycle. Wipe ~/.zeroclaw/state/matrix/ manually and restart.","messagePattern":"matrix: corruption recovery looped — aborting to avoid an infinite restart cycle\\. Wipe ~/\\.zeroclaw/state/matrix/ manually and restart\\.","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"critical","filePath":"crates/zeroclaw-channels/src/matrix.rs","lineNumber":1329,"sourceCode":"        blob: &session::SessionBlob,\n    ) -> bool {\n        let Some(want) = config.user_id.as_deref().filter(|s| !s.is_empty()) else {\n            return false;\n        };\n        if !want.contains(':') {\n            return false;\n        }\n        want != blob.user_id.as_str()\n    }\n\n    async fn build_attempt(\n        config: &MatrixConfig,\n        state_dir: &Path,\n        recovery_attempts: u32,\n    ) -> Result<Client> {\n        // Hard recursion bound: at most one auto-wipe + relogin cycle per call.\n        if recovery_attempts > 1 {\n            bail!(\n                \"matrix: corruption recovery looped — aborting to avoid an infinite restart cycle. \\\n                 Wipe ~/.zeroclaw/state/matrix/ manually and restart.\"\n            );\n        }\n\n        let saved = session::load(state_dir)?;\n\n        // A saved session that belongs to a different account would run this\n        // channel block as the wrong Matrix identity. Wipe and re-login fresh\n        // under the configured account instead of impersonating.\n        if let Some(blob) = saved.as_ref()\n            && saved_session_is_foreign(config, blob)\n        {\n            return recover_or_bail(\n                config,\n                state_dir,\n                recovery_attempts,\n                &format!(","sourceCodeStart":1311,"sourceCodeEnd":1347,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-channels/src/matrix.rs#L1311-L1347","documentation":"Matrix client startup wraps session loading in bounded auto-recovery: corrupted persisted state triggers a wipe of the state directory plus a fresh login, retried via build_attempt with a recovery_attempts counter. Anything above 1 aborts with this message - a hard recursion bound so a wipe-then-relogin cycle cannot loop forever. Seeing it means corruption (or a login failure indistinguishable from it) recurred even after the automatic wipe already ran once.","triggerScenarios":"Starting the Matrix channel when the persisted session under the state_dir is corrupted; build_attempt wipes state and re-logins (recovery_attempts 0 to 1), and the freshly created session fails or corrupts again, so the recursive attempt sees recovery_attempts > 1.","commonSituations":"Disk/filesystem problems or a full disk repeatedly truncating session files; a homeserver that keeps invalidating the new session (forced password change, security policy); containers remounting a broken or non-persistent state volume; clock skew making fresh sessions look invalid.","solutions":["Stop the agent and wipe the state directory manually, as the message says: rm -rf ~/.zeroclaw/state/matrix/ , then restart.","If it recurs after a manual wipe, check disk health and free space on the volume backing the state dir - a failing or full disk re-corrupts every new session.","Verify the homeserver is reachable and credentials are valid so the fresh login after the wipe succeeds (set channels.matrix.user-id and password).","On containers, ensure the state volume is persistent and writable, and the clock is NTP-synced."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"match build_matrix_client(&config, &state_dir, 0).await {\n    Ok(client) => client,\n    Err(err) if err.to_string().contains(\"corruption recovery looped\") => {\n        // escalate to the operator instead of restarting: a naive supervisor\n        // would re-trigger the same wipe/relogin loop\n        shutdown_with_alert(\"matrix state dir needs manual wipe\", &state_dir);\n        return Err(err);\n    }\n    Err(err) => return Err(err),\n}","preventionTips":["Run the state dir on a persistent, healthy volume; monitor free space and disk errors.","Configure channels.matrix.user-id and password so auto-recovery can re-authenticate after a wipe.","Do not use a naive restart-on-exit supervisor against this error - alert a human instead.","Keep system clocks NTP-synced; skewed clocks can invalidate freshly minted sessions."],"tags":["matrix","recovery","corruption","restart-loop","state-dir"],"backgroundTag":"crash-loop-detected","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}