You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A WhatsApp-initiated unlink now leaves a durable audit record — the disconnect reason previously reached only the log, the webhook and the socket, so once the process restarted an unlink was indistinguishable over the API from an ordinary network drop; transient drops stay unaudited, so a reconnect storm still writes nothing.
The Go SDK has its first semantic version, sdk/go/v0.2.0 — until now the module proxy only served pseudo-versions, so callers could not pin a release at all.
rmyndharis-openwa 0.2.0 on PyPI — the first release through the trusted-publishing workflow, carrying everything the Python SDK gained since 0.1.0 in June.
rmyndharis/openwa 0.2.0 on Packagist — the first versioned PHP release since June; Composer users on a stable constraint were pinned to 0.1.0 while only dev-main moved.
Changed
An API request body with a Content-Encoding other than identity is now refused with 415 — the aggregate in-flight body cap counts wire bytes, so a compressed body was admitted on its compressed size and then inflated past the memory it was supposed to bound.
Fixed
A reconnect now force-kills a wedged browser before relaunching — when a Chromium that stopped responding also refused to shut down, the automatic reconnect launched its replacement against the same browser profile while the old process could still be holding it, so the retry could fail on the very condition it was recovering from.
Saving the Infrastructure page no longer overwrites a saved engine with the one an environment variable pins — the engine radio seeded from the running engine even when ENGINE_TYPE pinned it, so saving any field on that page persisted the pinned value into data/.env.generated and unsetting the variable could no longer restore the engine the operator had chosen.
A WhatsApp-initiated unlink now clears a session's stored credentials once rather than twice — whatsapp-web.js can raise the logout event more than once for a single unlink and nothing deduplicated it, so the repeats raced each other and a still-open browser into the ENOTEMPTY failure the removal now carries the retry budget to survive.
A reaction to a message the gateway never stored no longer vanishes — the message.reaction webhook and the dashboard stream were both gated on the stored row, so a reaction to an ephemeral message, or to one that arrived before the session went live, was dropped with no error and no log.
MEDIA_DOWNLOAD_ENABLED is now validated at boot — it is read as "anything that is not false/0/no", so a typo left inbound media being decrypted and base64-inlined into every message row instead of disabling it. Only true/false/1/0/yes/no are accepted now, so a spelling like on that used to work will fail startup until it is changed.
A data export now bounds the inline media it carries — base64 inflates a single 50 MiB attachment to 66 MiB, past the import's own 25mb request-body limit, so a backup could export cleanly and then be refused with 413 on restore. EXPORT_INLINE_MEDIA_BUDGET_BYTES (8 MiB by default) caps the total across messages and bulk batches, spending it newest-first within each table and serving messages before batches, and an over-budget message payload exports as the omitted marker while a bulk-batch entry simply loses its base64; a URL-referenced payload is never dropped whatever the case of its scheme, and a large enough text-only history can still exceed the limit.
A data import now carries each session's ownership lease by its remaining time instead of its original deadline — a restore re-applied the deadline unchanged, so one that ran longer than a claim had left committed that claim as expired, including claims held by other nodes whose engines never stopped.
A refused data import no longer offers a retry that stops live engines — the one refusal whose retry is destructive now carries IMPORT_WOULD_ORPHAN_ENGINES and the dashboard matches it positively, so a refusal that only asks the operator to wait can no longer present a confirm whose OK re-runs the replace-all with stopOrphans=true.
A data import is refused with 409 when another transaction holds the connection — on SQLite it would otherwise nest inside that transaction and commit into it rather than to disk, so a restore reported as successful could vanish with that transaction's rollback.
A second data import while one is running is now refused with 409 — on SQLite both shared a single transaction, so the second one's rollback discarded a restore the first had already reported as successful.
A replace-all data import no longer disturbs the engines it left running — the restore dropped each session's ownership lease and, on SQLite, the heartbeat could read the half-applied transaction, so a renewal concluded the claim was lost and tore down engines that had never stopped.