WhatsApp showed the message delivered and the DB row reached read, but the ReplyBox bubble stayed on the queued clock forever.
FixmergeMessage made delivery status monotonic, and reconnect now invalidates inbox queries once.
Media was visible in WhatsApp, but ReplyBox rendered a blank tile or "Couldn't load media". Raw Baileys crypto material was serialized in a shape that could not revive Buffers.
FixBufferJSON serialization, legacy numeric-key revival, socket-backed reupload, and tests for both raw shapes.
ButThe first reupload fix was unreachable dead code; Bug 3 is the real recovery fix.
Rows were written off as expired CDN failures even though the phone still had the file. Baileys threw a Boom with err.output.statusCode, while its retry gate checked only flat err.status.
FixisReuploadRequired() reads both error shapes; downloadAndUpload catches, calls sock.updateMediaMessage(), then downloads again.
Copy fixUI changed from "WhatsApp no longer has this file" to "Couldn't download / WhatsApp didn't return the file / Try again".
Every media bubble sat on the spinner while sends remained unaffected. Three hung jobs occupied all MEDIA_WORKER_CONCURRENCY=3 slots for 40+ minutes.
FixStructural deadlines for media/avatar jobs, real request timeouts, stalled-slot monitoring, and dead base-id eviction before enqueue.
Ops noteClearing Redis does not free a pinned JS promise. The deploy and connector restart are the mitigation.