One fix, from #56 — and @LeeNX diagnosed it himself before I got there.
Three of his Cloudflare tunnels updated. All three failed their healthcheck. All three rolled back cleanly. He was told none of it.
send_message handed Telegram whatever it was given. Past 4096 characters Telegram rejects the whole message with ok: false; the code then retried once without Markdown — which does nothing about length — and returned the failed result to a caller that never looks at it. The notification simply vanished.
It is the worst possible thing to lose silently: the report you only need when something went wrong is also the longest one there is. A clean run is three lines. Three containers rolling back with their healthcheck logs is several thousand characters.
Splitting now lives in send_message rather than at the call sites. There was already one hand-rolled split — inline, inside /status — and the path producing the longest messages did not have it.
Chunks break on line boundaries and carry an open ``` fence across the break. That part is not cosmetic: an update report carries rollback logs in fenced blocks, and a chunk ending mid-fence renders as literal backticks in one message and swallows the next one as code. Splitting naively would have turned a truncation bug into a corruption bug. Buttons ride on the last chunk, since they act on the whole report rather than on whichever piece they happen to sit under.
Short messages take exactly the path they always did — asserted in the tests, because this sits underneath every notification the project sends.
Still open from the same report
The check announced current: 2026-06-18 while the pull immediately afterwards reported 2026-07-23 → 2026-07-23. Two sources for "what is running locally", disagreeing with each other. That wants measuring rather than guessing, so it is not in this release.
Upgrading is the usual docker pull ghcr.io/amayer1983/docksentry:latest, or nothing at all with auto-selfupdate on.