Skip to content

fix(config): prevent .env sanitizer from corrupting GLM_API_KEY and other suffix-trap keys#17273

Closed
searchonedev wants to merge 1 commit into
NousResearch:mainfrom
searchonedev:fix/sanitize-env-suffix-trap
Closed

fix(config): prevent .env sanitizer from corrupting GLM_API_KEY and other suffix-trap keys#17273
searchonedev wants to merge 1 commit into
NousResearch:mainfrom
searchonedev:fix/sanitize-env-suffix-trap

Conversation

@searchonedev

Copy link
Copy Markdown

Summary

The _sanitize_env_lines() function in hermes_cli/config.py silently corrupts API keys on every startup. It uses str.find() to detect accidentally-concatenated KEY=VALUE pairs, but since LM_API_KEY is a substring of GLM_API_KEY, scanning GLM_API_KEY=abc123 finds LM_API_KEY= at position 1, triggering a false split into G and LM_API_KEY=abc123.

Because sanitize_env_file() is called unconditionally from migrate_config() on every startup, the .env file gets rewritten with the corruption each time.

Affected key pairs (5 total)

Suffix key (skipped) Parent key that triggers false positive
LM_API_KEY GLM_API_KEY
LM_BASE_URL GLM_BASE_URL
LANGFUSE_PUBLIC_KEY HERMES_LANGFUSE_PUBLIC_KEY
LANGFUSE_SECRET_KEY HERMES_LANGFUSE_SECRET_KEY
LANGFUSE_BASE_URL HERMES_LANGFUSE_BASE_URL

Fix

Pre-compute a "suffix traps" set of known keys that are suffixes of other known keys, and skip them during the scan. This eliminates substring false-positives while still correctly splitting truly concatenated lines.

Testing

  • GLM_API_KEY=value → unchanged (was split into G + LM_API_KEY=value)
  • LM_API_KEY=value → unchanged (still works standalone)
  • HERMES_LANGFUSE_PUBLIC_KEY=value → unchanged
  • OPENROUTER_API_KEY=abcGOOGLE_API_KEY=def → correctly split into 2 lines (real concatenation still handled)

…nd other suffix-trap keys

The .env sanitizer uses str.find() to detect concatenated KEY=VALUE pairs.
Since LM_API_KEY is a suffix of GLM_API_KEY, scanning a line like
GLM_API_KEY=abc123 finds LM_API_KEY= at position 1, triggering a false
split into 'G' and 'LM_API_KEY=abc123'. This corrupts the key on every
startup because sanitize_env_file() is called from migrate_config().

Same issue affects LM_BASE_URL/GLM_BASE_URL and the three
LANGFUSE_* / HERMES_LANGFUSE_* pairs.

Fix: pre-compute a set of 'suffix trap' keys (known keys that are
suffixes of other known keys) and skip them during the scan. This
eliminates substring false-positives while still correctly splitting
truly concatenated lines.

Affected pairs:
- LM_API_KEY inside GLM_API_KEY
- LM_BASE_URL inside GLM_BASE_URL
- LANGFUSE_PUBLIC_KEY inside HERMES_LANGFUSE_PUBLIC_KEY
- LANGFUSE_SECRET_KEY inside HERMES_LANGFUSE_SECRET_KEY
- LANGFUSE_BASE_URL inside HERMES_LANGFUSE_BASE_URL
@alt-glitch alt-glitch added type/bug Something isn't working P1 High — major feature broken, no workaround comp/cli CLI entry point, hermes_cli/, setup wizard area/config Config system, migrations, profiles labels Apr 29, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Likely duplicate of #17141 — same root cause (suffix collision in _sanitize_env_lines) and same fix approach. Also competes with #17241. All fix #17138.

@searchonedev

Copy link
Copy Markdown
Author

Likely duplicate of #17141 — same root cause (suffix collision in _sanitize_env_lines) and same fix approach. Also competes with #17241. All fix #17138.

oh ok thanks! ive never done a PR before :)

@kshitijk4poor

Copy link
Copy Markdown
Collaborator

Thanks @searchonedev — closing as already-fixed on main via a different (but functionally equivalent) approach.

Your PR identified a real bug: _sanitize_env_lines used str.find() to detect concatenated KEY=VALUE pairs, which falsely split GLM_API_KEY=... at the LM_API_KEY= substring (same for HERMES_LANGFUSE_* vs LANGFUSE_*). Your fix was to maintain a pre-computed "suffix traps" set.

The fix landed on main uses an overlap-range approach instead: collect ALL needle match ranges, then drop any range that's fully contained within a longer overlapping needle (hermes_cli/config.py:4400-4457, with an explicit code comment naming the LM_API_KEY / GLM_API_KEY case). Functionally equivalent — both approaches prevent the false split — and it doesn't require maintaining a separate suffix-traps registry as new env keys are added.

Closing as redundant. Your diagnosis pinpointed the issue correctly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/config Config system, migrations, profiles comp/cli CLI entry point, hermes_cli/, setup wizard P1 High — major feature broken, no workaround type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants