hermes - 💡(How to fix) Fix gateway.session_context empty context values fall back to stale HERMES_SESSION_* env vars [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#13828Fetched 2026-04-23 07:48:45
View on GitHub
Comments
1
Participants
2
Timeline
4
Reactions
0
Timeline (top)
labeled ×3commented ×1

get_session_env() treats an explicitly empty context value as “unset” and falls back to os.environ. In gateway code, missing per-message fields are intentionally written as empty strings, so stale process-level HERMES_SESSION_* values can leak into unrelated message handling.

Root Cause

Because the check is truthiness-based instead of is not None, an explicit empty string does not shadow os.environ. That makes task-local session context non-authoritative whenever the process environment still contains an older HERMES_SESSION_* value.

Code Example

value = var.get()
if value:
    return value
return os.getenv(name, default)

---

import os
from gateway.session_context import set_session_vars, clear_session_vars, get_session_env

os.environ['HERMES_SESSION_THREAD_ID'] = '42'
tokens = set_session_vars(thread_id='')
try:
    print(get_session_env('HERMES_SESSION_THREAD_ID', ''))
finally:
    clear_session_vars(tokens)
    os.environ.pop('HERMES_SESSION_THREAD_ID', None)

---

42
RAW_BUFFERClick to expand / collapse

Summary

get_session_env() treats an explicitly empty context value as “unset” and falls back to os.environ. In gateway code, missing per-message fields are intentionally written as empty strings, so stale process-level HERMES_SESSION_* values can leak into unrelated message handling.

Affected code

  • gateway/session_context.py:110-128
  • gateway/run.py:6975-6983

Why this is a bug

GatewayRunner._set_session_env() deliberately normalizes absent fields like thread_id, user_id, and user_name to "" before storing them in contextvars.

But get_session_env() does:

value = var.get()
if value:
    return value
return os.getenv(name, default)

Because the check is truthiness-based instead of is not None, an explicit empty string does not shadow os.environ. That makes task-local session context non-authoritative whenever the process environment still contains an older HERMES_SESSION_* value.

Minimal reproduction

import os
from gateway.session_context import set_session_vars, clear_session_vars, get_session_env

os.environ['HERMES_SESSION_THREAD_ID'] = '42'
tokens = set_session_vars(thread_id='')
try:
    print(get_session_env('HERMES_SESSION_THREAD_ID', ''))
finally:
    clear_session_vars(tokens)
    os.environ.pop('HERMES_SESSION_THREAD_ID', None)

Observed output:

42

Expected behavior

An explicit empty contextvar value should override stale os.environ state, so the call above should return "".

Actual behavior

get_session_env() falls back to os.environ and returns the stale value ("42").

Suggested investigation

  • Treat contextvar values as authoritative whenever the variable has been set, even if the value is "".
  • Add a regression test covering empty-string overrides for thread_id, user_id, and user_name.

extent analysis

TL;DR

The get_session_env() function should be modified to treat empty string context values as authoritative, rather than falling back to os.environ.

Guidance

  • Modify the get_session_env() function to check for None instead of truthiness, allowing empty string values to override os.environ.
  • Add a regression test to cover empty-string overrides for thread_id, user_id, and user_name to prevent similar issues in the future.
  • Review the gateway/session_context.py and gateway/run.py files to ensure that the changes do not introduce any unintended side effects.
  • Consider adding a check to ensure that the contextvars module is being used correctly, as it seems to be a key part of the issue.

Example

value = var.get()
if value is not None:
    return value
return os.getenv(name, default)

Notes

This fix assumes that the intention is to treat empty string values as valid and authoritative. If this is not the case, further investigation may be needed to determine the correct behavior.

Recommendation

Apply the workaround by modifying the get_session_env() function to check for None instead of truthiness, as this will allow empty string values to override os.environ and prevent stale values from being used.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

An explicit empty contextvar value should override stale os.environ state, so the call above should return "".

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING