3.0 KiB
openclaw/wacli PR 443: recover app state when the phone shares a key without data
Metadata
| Field | Value |
|---|---|
| Institute | Molodetz Institute — Research & Retrieval Division |
| Subject | whatsapp-automation |
| Document type | Source Dossier |
| Tier | 1 |
| Source title | fix(sync): recover app state when the phone shares a key without data (PR 443) |
| Source URL | https://github.com/openclaw/wacli/pull/443 |
| Source publisher / author | Jarek Zmudzinski |
| Source type | repository |
| Source date (published) | 2026-09-26 |
| Date researched | 2026-10-27 |
| Researched by | tai (agent), model: Muse Spark, on behalf of retoor |
| Research method | direct page fetch (patch, first commit of seven plus headers) |
| Confidence | High for the empty-share finding, Medium for the recovery flow (later commits not read) |
| Status | Active |
Summary
wacli observed the phone answering a key request with a key share whose keys carry no key data. Storing that row crashed every sync on NOT NULL constraint failed: whatsmeow_app_state_sync_keys.key_data. The fix stops storing data-less keys and instead recovers affected collections through a full sync plus a phone recovery snapshot, rather than waiting for a key that never arrives. A test notes whatsmeow's own fetch on connect can trigger the key request, so the empty share may arrive before the client has seen any collection fail.
Key findings
- An empty key share is a real phone behavior: the key id is present, the key data is absent (the primary has nothing to give).
- Storing it is actively harmful: every later sync trips over the dataless row.
- The recovery path is full sync first, then a
COMPANION_SYNCD_SNAPSHOT_FATAL_RECOVERYpeer request (unencrypted collection copy) when the full sync still misses the key. - Chat-state writes otherwise wait up to five minutes for a key delivery that never comes; the fix skips the wait once the primary's answer is known to be empty.
Pros / strengths
- Distinguishes three states the naive code conflates: key received, answered-but-empty, never answered. Only the last one should keep waiting.
- Recovery degrades gracefully (full sync, then snapshot request) instead of erroring the whole sync.
Cons / limitations / caveats
- Only the first of seven commits was read here; the snapshot-request mechanics were verified separately against whatsmeow main (
BuildAppStateRecoveryRequest,handleAppStateRecovery) rather than from this PR. - wacli-specific scaffolding (fakeWA, recovery workers) does not transfer to detz.
Relevance to tai
Ported as state handling, not as the full recovery flow: WaClient::handle_message counts stored vs empty keys, logs an empty answer explicitly, ends the key wait (app_keys_answered_), and leaves the collection at version 0 so the next login retries the full sync. The fatal-recovery snapshot request is a documented gap, not built. Covered by build/whatsapp_test section empty key share.
Changelog
| Date | Change |
|---|---|
| 2026-10-27 | Initial dossier created. |