{"record":{"id":"5e4985fd6459b9a4","repo":"zeroclaw-labs/zeroclaw","slug":"device-exists-but-failed-to-load","errorCode":null,"errorMessage":"Device exists but failed to load","messagePattern":"Device exists but failed to load","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-channels/src/whatsapp_web.rs","lineNumber":2719,"sourceCode":"                &format!(\"channel starting (session: {})\", expanded_session_path)\n            );\n\n            // Initialize storage backend\n            let storage = RusqliteStore::new(&expanded_session_path)?;\n            let backend = Arc::new(storage);\n\n            // Check if we have a saved device to load\n            let mut device = Device::new(backend.clone());\n            if backend.exists().await? {\n                ::zeroclaw_log::record!(\n                    INFO,\n                    ::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Note),\n                    \"found existing session, loading device\"\n                );\n                if let Some(core_device) = backend.load().await? {\n                    device.load_from_serializable(core_device);\n                } else {\n                    anyhow::bail!(\"Device exists but failed to load\");\n                }\n                if let Some(ref pn) = device.pn\n                    && let Some(digits) = Self::store_jid_digits(&self.bot_phone, pn.user())\n                {\n                    ::zeroclaw_log::record!(\n                        INFO,\n                        ::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Note),\n                        &format!(\"pre-resolved bot phone from saved session: +{}\", digits)\n                    );\n                }\n                if let Some(ref lid) = device.lid\n                    && let Some(digits) = Self::store_jid_digits(&self.bot_lid, lid.user())\n                {\n                    ::zeroclaw_log::record!(\n                        INFO,\n                        ::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Note),\n                        &format!(\"pre-resolved bot LID from saved session: {}\", digits)\n                    );","sourceCodeStart":2701,"sourceCodeEnd":2737,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-channels/src/whatsapp_web.rs#L2701-L2737","documentation":"On startup with existing session files, the storage backend's `load()` is expected to return the persisted device; `Ok(None)` means the session store exists but no device could be materialized from it. The channel treats this as inconsistent session state and bails rather than silently re-pairing and orphaning the session.","triggerScenarios":"Corrupted, partially written, or schema-mismatched session state: a crash or power loss mid-write, a disk-full event, empty session files, or a zeroclaw version whose session format differs from the one that wrote the files.","commonSituations":"Process killed during session save; session directory on a full or flaky disk; downgrading or upgrading zeroclaw across incompatible session schemas.","solutions":["Back up and remove the session directory (paths are reported at startup), then pair again with a fresh QR scan.","Check permissions and free space on the session path.","If the session must be preserved, reproduce with the exact version that created it and report the corruption upstream."],"exampleFix":"// handle the startup error: purge the unusable session and re-pair\nmatch channel.listen(tx).await {\n    Err(e) if e.to_string().contains(\"Device exists but failed to load\") => {\n        for p in session_file_paths(&session_dir) {\n            let _ = std::fs::remove_file(p);\n        }\n        channel.listen(tx).await?; // fresh QR pairing\n    }\n    other => other?,\n}","handlingStrategy":"fallback","validationCode":"// Pre-flight the session at startup before relying on the channel\nfor p in session_file_paths(&session_dir) {\n    if std::fs::metadata(&p).map(|m| m.len() == 0).unwrap_or(false) {\n        anyhow::bail!(\"session file {} is empty; purge and re-pair before starting\", p.display());\n    }\n}","typeGuard":null,"tryCatchPattern":"match channel.listen(tx).await {\n    Err(e) if e.to_string().contains(\"Device exists but failed to load\") => {\n        // session state is unusable: back it up, purge, and re-pair with a fresh QR\n        backup_session_dir(&session_dir);\n        purge_session_files(&session_dir);\n        channel.listen(tx).await\n    }\n    other => other,\n}","preventionTips":["Keep session storage on reliable disk; avoid killing the process mid-session-write.","Back up the session directory before zeroclaw upgrades and downgrades.","Alert on this failure at startup — silent re-pairing would hide session corruption."],"tags":["whatsapp-web","session","persistence","rust"],"backgroundTag":"session-load-failed","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}