Files
tai/research/whatsapp-automation/github-openclaw-wacli-pull-443.md
T

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. |