Skip to content

fix(env): guard malformed numeric env vars across gateway/agent with utils helpers - #49558

Merged
kshitijk4poor merged 2 commits into
mainfrom
salvage/env-var-guards-48735
Jun 20, 2026
Merged

fix(env): guard malformed numeric env vars across gateway/agent with utils helpers#49558
kshitijk4poor merged 2 commits into
mainfrom
salvage/env-var-guards-48735

Conversation

@kshitijk4poor

Copy link
Copy Markdown
Collaborator

Summary

Malformed numeric env vars no longer crash adapter/agent init. A stale .env with HERMES_API_TIMEOUT=abc, a typo'd EMAIL_SMTP_PORT, or any non-numeric value previously raised an unhandled ValueError and took down gateway platform startup. This converts the remaining genuinely-unguarded int/float(os.getenv()) casts to the canonical utils.env_int / utils.env_float helpers, which return the default on empty/missing/non-numeric input.

Salvaged from #48735 (@annguyenNous) and widened to the whole bug class.

Changes

  • utils.py: add env_float() helper alongside the existing env_int() (salvaged from fix(api-server): guard HERMES_MAX_ITERATIONS against malformed env var #48735, authorship preserved).
  • Convert 22 unguarded sites to env_int/env_float:
    • gateway/config.pyWECOM_CALLBACK_PORT, BLUEBUBBLES_WEBHOOK_PORT
    • gateway/platforms/email.pyEMAIL_IMAP_PORT, EMAIL_SMTP_PORT, EMAIL_POLL_INTERVAL
    • gateway/platforms/feishu.py — dedup cache + text/media batch settings
    • gateway/platforms/wecom.py, plugins/platforms/discord/adapter.py — text batch delays
    • gateway/platforms/telegram.py — media batch delay, TELEGRAM_WEBHOOK_PORT
    • gateway/platforms/whatsapp.pyWHATSAPP_NPM_INSTALL_TIMEOUT
    • hermes_cli/auth.py — Codex/xAI OAuth refresh timeouts
    • agent/chat_completion_helpers.py — API / stream-read / stream-stale timeouts
    • run_agent.py, agent/auxiliary_client.py — API + Nous credential timeouts

Sites already guarded by try/except or local helpers are left untouched. HERMES_MAX_ITERATIONS is already guarded on main via _current_max_iterations(), so it is not re-touched here — #48735's api_server.py change was redundant and dropped.

Why the canonical helper (not per-module helpers / inline try-except)

utils.env_int/env_float is the established house pattern (already imported in chat_completion_helpers.py, runtime_provider.py, kanban_specify.py). Each conversion is a one-line swap that preserves the original default exactly. Config-fallback patterns like extra.get("webhook_host") or os.getenv(...) are intentionally left unconverted — env_* can't replicate the or fallback.

Validation

Before After
EMAIL_SMTP_PORT=abc → EmailAdapter init ValueError crash falls back to 587
HERMES_WECOM_TEXT_BATCH_DELAY_SECONDS=abc → WeComAdapter init ValueError crash falls back to 0.6
env_int/env_float on abc/empty/missing n/a returns default
good numeric values parsed parsed (unchanged)
  • E2E: constructed EmailAdapter / WeComAdapter with malformed env — both fall back to defaults instead of crashing.
  • tests/gateway/test_email.py + test_config.py + test_config_env_bridge_authority.py + test_feishu_bot_admission.py: 201 passed.
  • ruff check on all changed files: clean.

Credit: @annguyenNous (#48735env_float helper + canonical-helper approach).

annguyenNous and others added 2 commits June 20, 2026 14:00
Mirrors the existing env_int() helper: returns the default when the
variable is unset or non-numeric instead of raising ValueError. Used by
the follow-up commit to guard malformed float env vars across the gateway.

Salvaged from #48735 (@annguyenNous). The PR's api_server.py change is
now redundant — main guards HERMES_MAX_ITERATIONS via
_current_max_iterations().
…s helpers

Widen the env_float() guard from #48735 across the whole bug class: a
non-numeric value (e.g. a stale .env "HERMES_API_TIMEOUT=abc" or a typo'd
port) raised an unhandled ValueError and crashed adapter/agent init.

Converts 22 genuinely-unguarded first-party int/float(os.getenv()) sites to
the canonical utils.env_int / utils.env_float helpers (the established house
pattern), instead of duplicating per-module helpers or inline try/except:

- gateway/config.py: WECOM_CALLBACK_PORT, BLUEBUBBLES_WEBHOOK_PORT
- gateway/platforms/email.py: EMAIL_IMAP/SMTP_PORT, EMAIL_POLL_INTERVAL
- gateway/platforms/feishu.py: dedup cache + text/media batch settings
- gateway/platforms/wecom.py, discord/adapter.py: text batch delays
- gateway/platforms/telegram.py: media batch delay, TELEGRAM_WEBHOOK_PORT
- gateway/platforms/whatsapp.py: WHATSAPP_NPM_INSTALL_TIMEOUT
- hermes_cli/auth.py: CODEX/XAI refresh timeouts
- agent/chat_completion_helpers.py: API/stream read/stale timeouts
- run_agent.py, agent/auxiliary_client.py: API + nous timeouts

Sites already guarded by try/except or local helpers are left untouched.
The HERMES_MAX_ITERATIONS sites are already guarded on main via
_current_max_iterations(), so they are not included.
@github-actions

Copy link
Copy Markdown
Contributor

🔎 Lint report: salvage/env-var-guards-48735 vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 11227 on HEAD, 11225 on base (🆕 +2)

🆕 New issues (2):

Rule Count
unresolved-attribute 2
First entries
run_agent.py:2984: [unresolved-attribute] unresolved-attribute: Object of type `Self@get_credits_spent_micros` has no attribute `_credits_session_start_micros`
tests/run_agent/test_credits_notices_toggle.py:76: [unresolved-attribute] unresolved-attribute: Unresolved attribute `_credits_session_start_micros` on type `AIAgent`

✅ Fixed issues (1):

Rule Count
invalid-assignment 1
First entries
tests/run_agent/test_credits_notices_toggle.py:76: [invalid-assignment] invalid-assignment: Object of type `None` is not assignable to attribute `_credits_session_start_micros` of type `int`

Unchanged: 5884 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

@alt-glitch alt-glitch added type/bug Something isn't working comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/gateway Gateway runner, session dispatch, delivery comp/cli CLI entry point, hermes_cli/, setup wizard comp/plugins Plugin system and bundled plugins platform/discord Discord bot adapter area/auth Authentication, OAuth, credential pools P2 Medium — degraded but workaround exists labels Jun 20, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Related: #48735 (salvaged predecessor — env_float helper + canonical-helper approach), and the wider env-guard rollout series #48365, #48368, #48298, #48771, #48773. This PR consolidates the whole malformed-numeric-env-var bug class onto utils.env_int/env_float, so it is the superset of those per-file PRs — related, not a duplicate. Triaged type/bug, P2.

@kshitijk4poor
kshitijk4poor merged commit ff50a88 into main Jun 20, 2026
35 checks passed
@kshitijk4poor
kshitijk4poor deleted the salvage/env-var-guards-48735 branch June 20, 2026 09:41
waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
habarmc1223-sudo pushed a commit to habarmc1223-sudo/hermes-agent-fluxmem that referenced this pull request Jul 8, 2026
santhreal pushed a commit to santhreal/hermes-agent that referenced this pull request Jul 13, 2026
Gravezzz pushed a commit to Gravezzz/hermes-agent that referenced this pull request Jul 21, 2026
leewenjie pushed a commit to leewenjie/hermes-agent that referenced this pull request Aug 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/auth Authentication, OAuth, credential pools comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cli CLI entry point, hermes_cli/, setup wizard comp/gateway Gateway runner, session dispatch, delivery comp/plugins Plugin system and bundled plugins P2 Medium — degraded but workaround exists platform/discord Discord bot adapter type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants