zeroclaw-labs/zeroclaw · error
Device exists but failed to load
Error message
Device exists but failed to load
What it means
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.
Source
Thrown at crates/zeroclaw-channels/src/whatsapp_web.rs:2719
&format!("channel starting (session: {})", expanded_session_path)
);
// Initialize storage backend
let storage = RusqliteStore::new(&expanded_session_path)?;
let backend = Arc::new(storage);
// Check if we have a saved device to load
let mut device = Device::new(backend.clone());
if backend.exists().await? {
::zeroclaw_log::record!(
INFO,
::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Note),
"found existing session, loading device"
);
if let Some(core_device) = backend.load().await? {
device.load_from_serializable(core_device);
} else {
anyhow::bail!("Device exists but failed to load");
}
if let Some(ref pn) = device.pn
&& let Some(digits) = Self::store_jid_digits(&self.bot_phone, pn.user())
{
::zeroclaw_log::record!(
INFO,
::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Note),
&format!("pre-resolved bot phone from saved session: +{}", digits)
);
}
if let Some(ref lid) = device.lid
&& let Some(digits) = Self::store_jid_digits(&self.bot_lid, lid.user())
{
::zeroclaw_log::record!(
INFO,
::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Note),
&format!("pre-resolved bot LID from saved session: {}", digits)
);View on GitHub (pinned to 88bb9c8533)
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.
Example fix
// handle the startup error: purge the unusable session and re-pair
match channel.listen(tx).await {
Err(e) if e.to_string().contains("Device exists but failed to load") => {
for p in session_file_paths(&session_dir) {
let _ = std::fs::remove_file(p);
}
channel.listen(tx).await?; // fresh QR pairing
}
other => other?,
} Defensive patterns
Strategy: fallback
Validate before calling
// Pre-flight the session at startup before relying on the channel
for p in session_file_paths(&session_dir) {
if std::fs::metadata(&p).map(|m| m.len() == 0).unwrap_or(false) {
anyhow::bail!("session file {} is empty; purge and re-pair before starting", p.display());
}
} Try / catch
match channel.listen(tx).await {
Err(e) if e.to_string().contains("Device exists but failed to load") => {
// session state is unusable: back it up, purge, and re-pair with a fresh QR
backup_session_dir(&session_dir);
purge_session_files(&session_dir);
channel.listen(tx).await
}
other => other,
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: Process killed during session save; session directory on a full or flaky disk; downgrading or upgrading zeroclaw across incompatible session schemas.
Related errors
- QR payload is empty
- Recipient cannot be empty
- Recipient `{trimmed}` does not contain a valid phone number
- TTS returned empty audio
- WhatsApp marker target {} is empty
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/5e4985fd6459b9a4.
Report an issue: GitHub.