Repository navigation
fix(gateway): keep pending /update completion notifications until the target platform reconnects - #39091
Merged
Conversation
… target platform reconnects
🔎 Lint report:
|
8 tasks done
RichardHojunJang
added a commit
to RichardHojunJang/hermes-agent
that referenced
this pull request
Aug 15, 2026
A stale `.update_pending.json` naming a platform this profile does not run pins a permanent retry loop for the life of the gateway. `_send_update_notification` treats "no adapter for the target platform" as a single case and always defers, preserving the markers so a reconnecting adapter can still be notified (the behaviour NousResearch#39091 added, which is correct for a platform that IS enabled and merely still connecting). But `config.platforms` is pre-seeded with disabled placeholders for the whole platform catalog, so a marker can name a platform with `enabled=False`. No adapter will ever appear for it. The watcher then polls every 2s, and each poll re-reads the marker, logs, and rewrites it -- forever. Observed on a Slack-only profile carrying an orphan marker that named telegram: a steady 0.5 lines/sec, ~43k lines/day, which grew to 78% of the gateway log (9,972 of 12,699 lines) before it was found. Split the two cases. When the target platform is provably not enabled for this profile, the target is unreachable by construction: consume the markers and log once at WARNING with the reason. When it is enabled, keep deferring exactly as before. The enabled-check fails open. A missing or unreadable config returns True, so an unexpected config shape keeps the existing retry behaviour and can never discard a deliverable notification; only a positive, readable `enabled=False` ends the retry. Tests: - disabled platform: markers consumed, no retry, nothing misdelivered - enabled but reconnecting: markers preserved (guards the discard path from over-reaching) - unreadable config: fails open to the old deferral Verified the first test fails on the unpatched tree (`assert False is True`) and that the other 17 tests in the class still pass there, so it pins this bug rather than the surrounding behaviour.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A
/updatecompletion notification now survives a late platform reconnect instead of being silently lost.Salvage of #38522 by @Frowtek, cherry-picked onto current main with authorship preserved.
Root cause
When
hermes updatefinishes but the target platform's adapter hasn't reconnected yet (common right after the restart the update triggers),_send_update_notificationfell through the send block and thefinallydeleted all completion markers — so the user never learned whether the update succeeded or timed out.Changes
gateway/run.py:_send_update_notificationdefers (returns False) and preserves the markers when the target adapter isn't connected yet, so a later retry delivers once it reconnects — symmetric with the existing "update still running" defer path. The completion-only watcher fallback now polls until delivery actually succeeds rather than giving up on the first completion check.tests/gateway/test_update_command.py,tests/gateway/test_update_streaming.py: regression coverage (markers preserved while offline; delivered exactly once after reconnect).Validation
pytest tests/gateway/test_update_command.py tests/gateway/test_update_streaming.py— 49/49 pass.Closes #38522.
Infographic