Skip to content

fix(config): warn when memory.provider is set alongside memory_enabled=false - #32816

Closed
briandevans wants to merge 1 commit into
NousResearch:mainfrom
briandevans:fix/config-warn-memory-provider-with-disabled-flag-32624
Closed

briandevans wants to merge 1 commit into
NousResearch:mainfrom
briandevans:fix/config-warn-memory-provider-with-disabled-flag-32624

Conversation

@briandevans

Copy link
Copy Markdown
Contributor

What does this PR do?

memory.provider controls whether an external memory plugin is loaded (watchdog, recall, capture, persona writes). memory_enabled / user_profile_enabled control only whether the LLM is told about the built-in memory tool in the system prompt. They do not gate the plugin loader — plugins/memory/__init__.py:316-318 only reads memory.provider.

Users (and assistant agents asked to "disable memory") read memory_enabled: false as "turn the whole subsystem off" and observe the plugin watchdog, recall traffic, and persona writes continuing anyway. The reporter spent ~14h debugging exactly this in #32624 Trap 1 before locating the actual gating logic.

This PR implements Option B from the issue: an additive validate_config_structure() warning that fires when memory.provider is non-empty AND (memory_enabled is false OR user_profile_enabled is false). Pure warning, no behavior change.

Audited siblings: validate_config_structure() is already wired into print_config_warnings() (called at CLI/gateway startup), so no extra plumbing is needed. Other config sections (custom_providers, fallback_model) follow the same ConfigIssue pattern — this addition mirrors them.

Related Issue

Fixes #32624 (Trap 1 only — Traps 2 and 3 are cleanly separable per the reporter's note and belong in follow-up PRs).

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • `hermes_cli/config.py` — extend `validate_config_structure()` with a memory-trap check. Warns when `memory.provider` is set but `memory_enabled` and/or `user_profile_enabled` is explicitly `false`. Single combined warning when both flags are off; whitespace-only provider treated as unset (matches the plugin loader).
  • `tests/hermes_cli/test_config_validation.py` — `TestMemoryProviderTrap` covers the bug scenario (warns), the recommended remediation (`provider: ""` → no warning), the healthy default (both flags true → no warning), the both-flags-false case (one combined warning, not two), whitespace handling, and a missing-section guard.

How to Test

  1. `uv run --with pytest --with pytest-xdist --with pytest-asyncio python3 -m pytest tests/hermes_cli/test_config_validation.py -v`
  2. Or set the bug-shape config in `~/.hermes/config.yaml`:
    ```yaml
    memory:
    provider: memory_tencentdb
    memory_enabled: false
    ```
  3. Run `hermes doctor` or start any CLI command — the warning prints on stderr:
    ```
    ⚠ memory.provider='memory_tencentdb' is set but memory_enabled=false — the plugin still loads (watchdog, recall, capture, persona writes) but the LLM is not told it has memory tools
    ```

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (`fix(config):`)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix (no unrelated commits)
  • I've run focused tests for the touched code and all pass (28/28)
  • I've added tests for my changes
  • I've tested on my platform: macOS 15.x

Documentation & Housekeeping

  • I've updated relevant documentation — N/A (warning text is self-documenting)
  • I've updated `cli-config.yaml.example` if I added/changed config keys — N/A (no new keys)
  • I've updated `CONTRIBUTING.md` or `AGENTS.md` if I changed architecture or workflows — N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — pure-Python config validator, no OS-specific code
  • I've updated tool descriptions/schemas if I changed tool behavior — N/A

Related / Positioning

Distinct from Burgunthy's open #30814 `fix(memory): prevent dead writes when memory_enabled is false`, which addresses runtime tool-dispatch for the in-process `MemoryStore` (Option C from the issue — behavior change at `tool_executor`). This PR is a purely additive config-load-time warning targeting the external plugin loader path the reporter actually hit (memory_tencentdb watchdog continuing for 14h despite `memory_enabled: false`). The two are complementary — both can land.

Copilot AI review requested due to automatic review settings May 26, 2026 21:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds config validation and tests to warn when an external memory.provider is configured while in-prompt memory flags are disabled, since plugin loading is gated by memory.provider rather than memory_enabled / user_profile_enabled.

Changes:

  • Add validate_config_structure warning when memory.provider is non-empty but memory_enabled and/or user_profile_enabled are false.
  • Add a focused test suite covering warning/no-warning cases for various memory configurations.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
tests/hermes_cli/test_config_validation.py Adds tests asserting the new warning behavior and its remediation hint.
hermes_cli/config.py Implements the new memory provider “trap” warning in config structure validation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread hermes_cli/config.py
Comment on lines +3637 to +3645
issues.append(ConfigIssue(
"warning",
f"memory.provider='{provider_name.strip()}' is set but "
f"{'/'.join(disabled_flags)}=false — the plugin still "
"loads (watchdog, recall, capture, persona writes) but "
"the LLM is not told it has memory tools",
"To fully disable the memory plugin, set "
"memory.provider: \"\" (empty string)",
))
Comment thread hermes_cli/config.py
Comment on lines +3639 to +3642
f"memory.provider='{provider_name.strip()}' is set but "
f"{'/'.join(disabled_flags)}=false — the plugin still "
"loads (watchdog, recall, capture, persona writes) but "
"the LLM is not told it has memory tools",
Comment thread hermes_cli/config.py
Comment on lines +3627 to +3629
provider_name = memory_cfg.get("provider")
if isinstance(provider_name, str) and provider_name.strip():
mem_enabled = memory_cfg.get("memory_enabled", True)
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists area/config Config system, migrations, profiles comp/cli CLI entry point, hermes_cli/, setup wizard labels May 26, 2026
@briandevans
briandevans force-pushed the fix/config-warn-memory-provider-with-disabled-flag-32624 branch 3 times, most recently from 49fcda5 to 3eddae5 Compare May 30, 2026 21:13
…d=false

`memory.provider` controls whether an external memory plugin is loaded
(watchdog, recall, capture, persona writes). `memory_enabled` and
`user_profile_enabled` control only whether the LLM is told it has a
memory tool in the system prompt — they do NOT gate the plugin loader
(see `plugins/memory/__init__.py:316-318`).

Users (and assistant agents asked to "disable memory") routinely read
`memory_enabled: false` as "turn the whole subsystem off" and observe
the plugin watchdog and persona writes continuing anyway. The reporter
spent ~14h debugging exactly this scenario before locating the gating
logic (see NousResearch#32624 Trap 1, Option B).

Add an additive `validate_config_structure()` warning that fires when
`memory.provider` is non-empty AND (`memory_enabled` is false OR
`user_profile_enabled` is false). Pure warning, no behavior change.

The fix is intentionally scoped to Trap 1 of NousResearch#32624 — Traps 2 and 3
(sticky-profile config redirection, per-profile log path visibility)
are cleanly separable per the issue reporter's note and belong in
follow-up PRs.
@briandevans

Copy link
Copy Markdown
Contributor Author

Closing to focus the queue on security/file-safety work where civilian merges are landing. Happy to reopen if maintainers want this picked up.

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 P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

3 participants