NousResearch/hermes-agent
Noisy raft CLI warning logged when raft unused
Cluster 49234 · agent. Data as of
Nothing open on GitHub. Fix merged in #49240 on 20 Jun 2026. Check it covers your case.
The short answer
0open issues
0open PRs
3items grouped
- Known?
- Yes. 3 related items grouped here, 2 issues already closed.
- Fix event
- A fix was merged to main in PR #49240. Check it covers your case. No release data is tracked.
- Tracker
- The maintainers' tracker marks this
partially resolved, deciding PR #49240. That is separate from the fix event. - Still open
- Nothing open on GitHub.
Reports and a fix for an unconditional warning message about the raft CLI being logged repeatedly, even when the raft platform plugin is disabled or the CLI is not installed.
Open issues0
Open PRs0
Fixes on record
-
#49240 fix(plugins): silence raft check_fn log spam for users without raft CLI
files:
plugins/platforms/raft/adapter.py,tests/plugins/test_raft_check_fn_silent.pyShow the diff
-
plugins/platforms/raft/adapter.py@@ -98,12 +98,20 @@ def check_raft_requirements() -> bool: - """Check if Raft channel dependencies are available.""" + """Check if Raft channel dependencies are available. + + Intentionally silent on failure — this is a passive probe registered as + the platform's ``check_fn``. It is called on every + ``load_gateway_config()`` (message handling, display lookups, agent + turns), so logging here floods the logs for every user without the + ``raft`` CLI installed. The caller (``gateway/platform_registry.py`` + ``create_adapter()``) emits its own warning when requirements are not met + and an adapter is actually requested. This matches the convention used by + other platform adapters (e.g. ``teams/adapter.py``). + """ if not AIOHTTP_AVAILABLE: - logger.warning("[raft] aiohttp is not installed — install with: pip install aiohttp") return False if not shutil.which("raft"): - logger.warning("[raft] raft CLI not found in PATH — install from https://raft.build") return False return True -
tests/plugins/test_raft_check_fn_silent.py@@ -0,0 +1,75 @@ +"""Regression tests for the raft platform plugin's check_fn. + +The raft platform adapter's ``check_raft_requirements()`` is registered as +the platform's ``check_fn``. This function is invoked on every +``load_gateway_config()`` call (dozens of times during normal gateway +operation). It must therefore be a *silent* predicate — returning True/False +without logging — otherwise every user without the ``raft`` CLI installed +gets their logs flooded with WARNING messages every few seconds. + +See: https://github.com/NousResearch/hermes-agent/issues/49234 +""" + +import logging +from unittest.mock import patch + +import pytest + + [redacted:email] +def raft_check(): + """Import check_raft_requirements fresh (adapter self-manages sys.path).""" + from plugins.platforms.raft.adapter import check_raft_requirements + + return check_raft_requirements + + +def test_check_returns_false_when_raft_cli_missing(raft_check): + """check_fn returns False when raft CLI is not in PATH.""" + with patch("plugins.platforms.raft.adapter.shutil.which", return_value=None), \ + patch("plugins.platforms.raft.adapter.AIOHTTP_AVAILABLE", True): + assert raft_check() is False + + +def test_check_returns_false_when_aiohttp_missing(raft_check): + """check_fn returns False when aiohttp dependency is unavailable.""" + with patch("plugins.platforms.raft.adapter.AIOHTTP_AVAILABLE", False): + assert raft_check() is False + + +def test_check_returns_true_when_all_deps_present(raft_check): + """check_fn returns True when all dependencies are available.""" + with patch("plugins.platforms.raft.adapter.shutil.which", return_value="/usr/bin/raft"), \ + patch("plugins.platforms.raft.adapter.AIOHTTP_AVAILABLE", True): + assert raft_check() is True + + +def test_check_silent_when_raft_cli_missing(raft_check, caplog): + """check_fn must NOT log a WARNING when raft CLI is missing. + + This is the regression guard for issue #49234 — logging inside check_fn + causes log spam because the function is called on every config load. + """ + with patch("plugins.platforms.raft.adapter.shutil.which", return_value=None), \ + patch("plugins.platforms.raft.adapter.AIOHTTP_AVAILABLE", True): + with caplog.at_level(logging.WARNING, logger="plugins.platforms.raft.adapter"): + raft_check() + + warnings = [r for r in caplog.records if r.levelno >= logging.WARNING] + assert warnings == [], ( + f"check_raft_requirements must be silent (no WARNING logs), " + f"but emitted: {[r.getMessage() for r in warnings]}" + ) + + +def test_check_silent_when_aiohttp_missing(raft_check, caplog): + """check_fn must NOT log a WARNING when aiohttp is missing.""" + with patch("plugins.platforms.raft.adapter.AIOHTTP_AVAILABLE", False): + with caplog.at_level(logging.WARNING, logger="plugins.platforms.raft.adapter"): + raft_check() + + warnings = [r for r in caplog.records if r.levelno >= logging.WARNING] + assert warnings == [], ( + f"check_raft_requirements must be silent (no WARNING logs), " + f"but emitted: {[r.getMessage() for r in warnings]}" + )
-
Closed issues · 2
How this cluster was grouped
-
Link evidence (
partly structural links): some members are connected by structural evidence (shared changed files, or a closing/superseded reference); the rest are joined by an automated relevance judgement over their text. - Members outside that structural core may belong to a different underlying problem.
-
Pairwise link density
0.45: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36.1.00means every pair is linked.
Pick up a Lab task
Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.
Open the LabAt a glance
- Subsystem
- agent
- Merged PRs
- #49240
- Closed issues
- 2
- Attempts
- 0 PRs closed without merging
- Fix link checked
- 20 Jun 2026