52 lines
3.0 KiB
Markdown
52 lines
3.0 KiB
Markdown
# 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_RECOVERY` peer 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. |
|