fix(gateway): coerce scalar free_response_channels to str before split - #14932
Closed
valda wants to merge 1 commit into
Closed
fix(gateway): coerce scalar free_response_channels to str before split#14932valda wants to merge 1 commit into
valda wants to merge 1 commit into
Conversation
YAML loads a bare numeric value such as
discord:
free_response_channels: 1491973769726791812
as an int. _discord_free_response_channels() / _slack_free_response_channels()
checked `isinstance(raw, list)` and `isinstance(raw, str)` in that order and
then fell through to `return set()`, so a single-channel config that happened
to be unquoted was silently dropped with no log line — the bot kept demanding
@mentions even though the channel was configured to free-response.
A multi-channel value like `1234567890,9876543210` does not trip this because
the comma forces YAML to parse it as a string. Single-channel configs are
the only case that breaks, which is exactly the footgun that's hardest to
diagnose (the config "looks right" and the feature just doesn't activate).
Note that the old-schema env-var bridge at gateway/config.py:614+ already
runs `str(frc)` when forwarding to SLACK_/DISCORD_FREE_RESPONSE_CHANNELS,
so the env-var fallback worked. The bug only surfaces on the
`config.extra["free_response_channels"]` path populated by the `platforms:`
bridge at gateway/config.py:576, which passes the raw YAML value through
unchanged.
Fix at the reader: treat any non-list value as a scalar, coerce with str(),
then apply the same CSV split semantics. This keeps the public contract
stable (list or str-like continues to work identically) while accepting
the ints that the YAML loader is free to hand us.
Added tests for both Discord and Slack covering:
- bare int value in config.extra
- list of ints in config.extra
Collaborator
|
Merged via PR #18553. Your commit was cherry-picked onto current main with your authorship preserved (rebase merge). Thanks for the contribution! 🎉 |
kshitijk4poor
added a commit
that referenced
this pull request
May 1, 2026
donald131
pushed a commit
to donald131/hermes-agent
that referenced
this pull request
May 2, 2026
Adds email→username mappings for: - priveperfumes (PR NousResearch#18456) - amroessam (PR NousResearch#17798) - Hinotoi-agent (PR NousResearch#9361) - valda (PR NousResearch#14932)
nickdlkk
pushed a commit
to nickdlkk/hermes-agent
that referenced
this pull request
May 11, 2026
Adds email→username mappings for: - priveperfumes (PR NousResearch#18456) - amroessam (PR NousResearch#17798) - Hinotoi-agent (PR NousResearch#9361) - valda (PR NousResearch#14932)
jsboige
pushed a commit
to jsboige/hermes-agent
that referenced
this pull request
May 14, 2026
Adds email→username mappings for: - priveperfumes (PR NousResearch#18456) - amroessam (PR NousResearch#17798) - Hinotoi-agent (PR NousResearch#9361) - valda (PR NousResearch#14932)
dannyJ848
pushed a commit
to dannyJ848/hermes-agent
that referenced
this pull request
May 17, 2026
Adds email→username mappings for: - priveperfumes (PR NousResearch#18456) - amroessam (PR NousResearch#17798) - Hinotoi-agent (PR NousResearch#9361) - valda (PR NousResearch#14932)
gweeteve
pushed a commit
to gweeteve/hermes-agent
that referenced
this pull request
Jun 2, 2026
Adds email→username mappings for: - priveperfumes (PR NousResearch#18456) - amroessam (PR NousResearch#17798) - Hinotoi-agent (PR NousResearch#9361) - valda (PR NousResearch#14932)
Seven74AI
pushed a commit
to Seven74AI/hermes-agent
that referenced
this pull request
Jun 13, 2026
Adds email→username mappings for: - priveperfumes (PR NousResearch#18456) - amroessam (PR NousResearch#17798) - Hinotoi-agent (PR NousResearch#9361) - valda (PR NousResearch#14932)
waefrebeorn
pushed a commit
to waefrebeorn/slermes
that referenced
this pull request
Jul 2, 2026
Adds email→username mappings for: - priveperfumes (PR NousResearch#18456) - amroessam (PR NousResearch#17798) - Hinotoi-agent (PR NousResearch#9361) - valda (PR NousResearch#14932)
Gravezzz
pushed a commit
to Gravezzz/hermes-agent
that referenced
this pull request
Jul 21, 2026
Adds email→username mappings for: - priveperfumes (PR NousResearch#18456) - amroessam (PR NousResearch#17798) - Hinotoi-agent (PR NousResearch#9361) - valda (PR NousResearch#14932)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A single-channel Discord/Slack
free_response_channelsentry configured as a bare numeric YAML value is silently dropped. The bot keeps demanding @mentions even though the channel was configured to free-response, with no log line to point at why.YAML loads the bare integer as
int._discord_free_response_channels()/_slack_free_response_channels()checkisinstance(raw, list)thenisinstance(raw, str), and if neither matches fall through toreturn set(). So any single-channel unquoted numeric ID is silently dropped — which is exactly the footgun that's hardest to diagnose, because the config file "looks right" and the feature just doesn't activate.A multi-channel value like
1234567890,9876543210doesn't trip this because the comma forces YAML to parse it as a string. And the old-schema env-var bridge atgateway/config.py:614+already runsstr(frc)when forwarding toSLACK_/DISCORD_FREE_RESPONSE_CHANNELS, so the env-var fallback worked. The bug only surfaces on theconfig.extra["free_response_channels"]path populated by theplatforms:bridge atgateway/config.py:576, which passes the raw YAML value through unchanged.Fix
Coerce any non-list scalar to
str()at the reader before applying the existing CSV split:This keeps the public contract stable — lists, CSV strings, empty strings,
None, and env-var fallbacks all continue to behave identically — while also accepting theint/floatscalars that the YAML loader is free to hand us.Applied symmetrically to both Discord and Slack since they share the exact same pattern.
Tests
Added unit tests covering:
intvalue inconfig.extra(the failure case)intentries inconfig.extrafor both Discord (
test_discord_free_response_channels_bare_int,test_discord_free_response_channels_int_list) and Slack (test_free_response_channels_bare_int,test_free_response_channels_int_list).Existing
test_free_response_channels_list/test_free_response_channels_csv_string/test_free_response_channels_empty_string/test_free_response_channels_env_var_fallback/test_discord_free_response_channel_can_come_from_config_extrastill pass unchanged.Alternative considered
Coercing at the bridge (
gateway/config.py:576) would fix this single field but would leave otherplatforms:-bridged fields with the same pattern (allow_from,group_allow_from,ignored_channels, …) still vulnerable to a different bare-int YAML footgun. Fixing at the reader is minimal, defensive, and scoped to the two adapters that actually consume this field. If the bridge ever grows a general normalization step that's a strictly bigger change, and this reader-level fix is still correct then.