hermes-agent/gateway/platforms
cifangyiquan 089f09fa5f fix(api_server): mark rejected API_SERVER_KEY as non-retryable fatal error
When _api_key_passes_startup_guard() rejects the key (missing,
placeholder/too short, or fail-closed unverifiable strength), connect()
returned a bare False with no fatal-error info. gateway.run's reconnect
watcher treats that as transient and re-queues with backoff forever —
each retry re-instantiating the adapter and its ResponseStore sqlite
connection. Observed in production (#37011): ~501 leaked connections
(1002 fds) over ~2.5 days until EMFILE made the whole gateway
unresponsive.

Set a non-retryable fatal error (api_server_key_invalid) in connect()
when the guard rejects, covering all three rejection branches, so the
platform drops from the reconnect queue; recover with
`/platform resume api_server` after fixing the key. Same treatment as
the port-conflict guard (api_server_port_in_use, #65665 / bda8bd76a8).

Tests mirror the port-conflict precedent: each rejection path asserts
connect() is False, has_fatal_error True, fatal_error_retryable False,
and fatal_error_code api_server_key_invalid, plus a strong-key control.

Re-implementation of #38803 by @cifangyiquan against current main —
their patch targeted the old inline guard in connect() which was since
extracted to _api_key_passes_startup_guard() (and gained the
fail-closed branch in 683059feb5), so the original diff no longer
applies. Their production diagnosis and non-retryable direction
preserved.

Refs: #38803, #37011
2026-07-23 11:54:19 -07:00
..
qqbot fix(security): pin DNS resolutions for SSRF-safe fetches 2026-07-23 11:44:43 -07:00
__init__.py perf(gateway): defer QQAdapter and YuanbaoAdapter imports via PEP 562 (#22790) 2026-05-09 13:17:48 -07:00
_http_client_limits.py fix(gateway): tighten httpx keepalive and close whatsapp typing-response leak (#18451) 2026-05-02 02:23:37 -07:00
ADDING_A_PLATFORM.md feat(gateway): inline choice pickers for /reasoning and /fast (Telegram, Discord, Matrix) (#65799) 2026-07-16 10:38:31 -07:00
api_server.py fix(api_server): mark rejected API_SERVER_KEY as non-retryable fatal error 2026-07-23 11:54:19 -07:00
base.py fix: close orphaned code fences on all send paths 2026-07-23 11:50:28 -07:00
bluebubbles.py security(gateway): set explicit client_max_size on 3 uncapped aiohttp servers (#59180) 2026-07-05 14:48:28 -07:00
helpers.py fix(discord): make reconnect recovery lifecycle-safe 2026-07-18 14:01:33 -07:00
msgraph_webhook.py fix(security): widen non-ASCII compare_digest crash fix to all sibling sites 2026-07-16 07:22:24 -07:00
signal.py fix(gateway): validate multiplex adapter config by platform 2026-07-16 05:39:58 -07:00
signal_format.py fix(signal): share markdown formatting across send paths 2026-06-20 13:47:14 +05:30
signal_rate_limit.py feat(gateway/signal): add support for multiple images sending 2026-04-30 04:28:08 -07:00
webhook.py fix(gateway): unify reset boundaries vs recovery — promote accidental ends, honor mode=none, adapter-aware resume guidance 2026-07-17 04:51:39 -07:00
webhook_filters.py feat(gateway): add webhook payload filters 2026-07-08 08:10:55 -07:00
weixin.py fix(gateway/platforms): migrate all Weixin fallbacks to get_secret() for consistent profile-scoped resolution 2026-07-16 05:39:58 -07:00
whatsapp_cloud.py fix(approval): honor allow_session across all button adapters 2026-07-21 12:04:47 -07:00
whatsapp_common.py feat(whatsapp): native Baileys polls, clarify-as-poll, locations, and rich inbound metadata 2026-07-05 06:27:20 -07:00
yuanbao.py feat(Yuanbao) optimizes media resource processing speed: parallel download 2026-07-08 08:05:45 -07:00
yuanbao_media.py fix(security): pin DNS resolutions for SSRF-safe fetches 2026-07-23 11:44:43 -07:00
yuanbao_proto.py feat(Yuanbao): support wechat forward msg (#43508) 2026-06-12 02:06:47 -07:00
yuanbao_sticker.py yuanbao platform (#16298) 2026-04-26 18:50:49 -07:00