Bug Description
This report was written with Claude's help (I'm not a developer).
When agent.disabled_toolsets in config.yaml contains a composite toolset
(e.g. coding), Hermes subtracts ALL of that composite's tools from the
final tool list — including tools belonging to toolsets the user has
explicitly ENABLED. Because coding contains every terminal and file
tool, a config that enables only terminal + file and disables coding
ends up sending the model ZERO tools.
There is no warning. The startup banner and /tools list show the tools as
enabled, /toolsets shows (*) terminal and (*) file, and hermes tools
shows Terminal & File ticked — but the verbose log shows:
✅ Enabled toolset 'terminal': close_terminal, process, read_terminal, terminal
✅ Enabled toolset 'file': patch, read_file, search_files, write_file
🚫 Disabled toolset 'coding': ... close_terminal, patch, process, read_file,
read_terminal, search_files, terminal, write_file ...
🛠️ No tools selected (all filtered out or unavailable)
API Request - Model: qwen3.6:35b-a3b, Messages: 1, Tools: 0
Downstream symptom (how users will actually experience this): the model,
receiving no tool definitions, improvises a tool call as plain text (e.g. a
<tool_use> XML block). Hermes renders it in the chat, nothing executes,
and the turn ends "✓ 0s" with no error. This looks exactly like the
Ollama streaming/tools bugs (#25629 etc.), which cost me a long
wild-goose chase before finding the real cause.
The codebase already protects against this exact footgun for hermes-*
platform bundles: in model_tools.py::_compute_tool_definitions, disabling
a hermes-* bundle subtracts only its non-core delta, citing #33924
("subtracting the whole bundle would strip core tools shared by other
enabled toolsets and empty the tool list"). That protection does not apply
to other composite toolsets like coding (or safe, debugging), which
subtract fully.
Steps to Reproduce
-
In ~/.hermes/config.yaml, enable only the terminal and file toolsets
(e.g. via the "Blank Slate" style minimal setup), and include coding
in agent.disabled_toolsets:
agent:
disabled_toolsets:
- coding
-
Run any tool-requiring prompt with verbose output:
hermes chat -v -q "run date +%s in terminal"
-
Observe the log: toolsets enable successfully, then
"No tools selected (all filtered out or unavailable)" and
"API Request ... Tools: 0".
-
Remove the - coding line from disabled_toolsets, re-run: tool list is
restored ("Final tool selection (6 tools)") and the command executes.
Expected Behavior
Explicitly enabled toolsets should not be silently gutted by disabling an
overlapping composite toolset. Either:
(a) extend the #33924 non-core-delta subtraction to all composite toolsets,
not just hermes-* bundles; or
(b) subtract only tools that don't also belong to an explicitly enabled
toolset; or at minimum
(c) print a loud warning when the disabled-toolsets subtraction leaves the
final tool list empty (or removes tools from an enabled toolset).
Actual Behavior
All terminal/file tools are stripped, the model receives Tools: 0, and it
falls back to hallucinating tool calls as plain text that render in the UI
but never execute ("✓ 0s"). Every status surface (/tools list, /toolsets,
hermes tools, startup banner) reports the tools as enabled, so the user has
no way to see the problem without -v.
Affected Component
Tools (terminal, file ops, web, code execution, etc.)
Messaging Platform (if gateway-related)
N/A (CLI only)
Debug Report
Debug report uploaded:
Report https://paste.rs/EDjJR
agent.log https://paste.rs/Izkpv
Operating System
macOS (Mac Studio, Apple Silicon)
Python Version
(run hermes dump | grep -i python and paste the version here)
Hermes Version
0.18.0 (2026.7.1), reproduced both before and after hermes update on 4 Jul 2026
Additional Logs / Traceback (optional)
Root Cause Analysis (optional)
model_tools.py::_compute_tool_definitions — the disabled_toolsets loop
special-cases names starting with "hermes-" (subtract bundle_non_core_tools
only, per #33924) but performs a full resolve_toolset() subtraction for all
other composite toolsets. Composites like coding are supersets of the
terminal and file toolsets, so disabling them empties an
explicitly-enabled minimal tool list.
Proposed Fix (optional)
Apply the same non-core / overlap-aware subtraction to all composite
toolsets, or warn when subtraction removes tools belonging to an enabled
toolset / empties the final list.
Are you willing to submit a PR for this?
Bug Description
This report was written with Claude's help (I'm not a developer).
When
agent.disabled_toolsetsin config.yaml contains a composite toolset(e.g.
coding), Hermes subtracts ALL of that composite's tools from thefinal tool list — including tools belonging to toolsets the user has
explicitly ENABLED. Because
codingcontains everyterminalandfiletool, a config that enables only
terminal+fileand disablescodingends up sending the model ZERO tools.
There is no warning. The startup banner and
/tools listshow the tools asenabled,
/toolsetsshows(*) terminaland(*) file, andhermes toolsshows Terminal & File ticked — but the verbose log shows:
Downstream symptom (how users will actually experience this): the model,
receiving no tool definitions, improvises a tool call as plain text (e.g. a
<tool_use>XML block). Hermes renders it in the chat, nothing executes,and the turn ends "✓ 0s" with no error. This looks exactly like the
Ollama streaming/tools bugs (#25629 etc.), which cost me a long
wild-goose chase before finding the real cause.
The codebase already protects against this exact footgun for
hermes-*platform bundles: in
model_tools.py::_compute_tool_definitions, disablinga
hermes-*bundle subtracts only its non-core delta, citing #33924("subtracting the whole bundle would strip core tools shared by other
enabled toolsets and empty the tool list"). That protection does not apply
to other composite toolsets like
coding(orsafe,debugging), whichsubtract fully.
Steps to Reproduce
In ~/.hermes/config.yaml, enable only the terminal and file toolsets
(e.g. via the "Blank Slate" style minimal setup), and include
codingin agent.disabled_toolsets:
agent:
disabled_toolsets:
- coding
Run any tool-requiring prompt with verbose output:
hermes chat -v -q "run date +%s in terminal"
Observe the log: toolsets enable successfully, then
"No tools selected (all filtered out or unavailable)" and
"API Request ... Tools: 0".
Remove the
- codingline from disabled_toolsets, re-run: tool list isrestored ("Final tool selection (6 tools)") and the command executes.
Expected Behavior
Explicitly enabled toolsets should not be silently gutted by disabling an
overlapping composite toolset. Either:
(a) extend the #33924 non-core-delta subtraction to all composite toolsets,
not just hermes-* bundles; or
(b) subtract only tools that don't also belong to an explicitly enabled
toolset; or at minimum
(c) print a loud warning when the disabled-toolsets subtraction leaves the
final tool list empty (or removes tools from an enabled toolset).
Actual Behavior
All terminal/file tools are stripped, the model receives Tools: 0, and it
falls back to hallucinating tool calls as plain text that render in the UI
but never execute ("✓ 0s"). Every status surface (/tools list, /toolsets,
hermes tools, startup banner) reports the tools as enabled, so the user has
no way to see the problem without -v.
Affected Component
Tools (terminal, file ops, web, code execution, etc.)
Messaging Platform (if gateway-related)
N/A (CLI only)
Debug Report
Operating System
macOS (Mac Studio, Apple Silicon)
Python Version
(run
hermes dump | grep -i pythonand paste the version here)Hermes Version
0.18.0 (2026.7.1), reproduced both before and after
hermes updateon 4 Jul 2026Additional Logs / Traceback (optional)
Root Cause Analysis (optional)
model_tools.py::_compute_tool_definitions — the disabled_toolsets loop
special-cases names starting with "hermes-" (subtract bundle_non_core_tools
only, per #33924) but performs a full resolve_toolset() subtraction for all
other composite toolsets. Composites like
codingare supersets of theterminalandfiletoolsets, so disabling them empties anexplicitly-enabled minimal tool list.
Proposed Fix (optional)
Apply the same non-core / overlap-aware subtraction to all composite
toolsets, or warn when subtraction removes tools belonging to an enabled
toolset / empties the final list.
Are you willing to submit a PR for this?