with one click
slack-aws-chatbot-thread-context-debugging
// Diagnose why Hermes cannot read Slack thread root messages from AWS Chatbot / Amazon Q alerts, and determine whether config changes or code changes are required.
// Diagnose why Hermes cannot read Slack thread root messages from AWS Chatbot / Amazon Q alerts, and determine whether config changes or code changes are required.
[HINT] Download the complete skill directory including SKILL.md and all related files
| name | slack-aws-chatbot-thread-context-debugging |
| description | Diagnose why Hermes cannot read Slack thread root messages from AWS Chatbot / Amazon Q alerts, and determine whether config changes or code changes are required. |
| version | 1.1.0 |
| author | Hermes Agent |
| license | MIT |
| metadata | {"hermes":{"tags":["slack","hermes","aws-chatbot","amazon-q","cloudwatch","thread-context","gateway","debugging"]}} |
Use this when Hermes is invoked in a Slack thread whose root message was posted by AWS Chatbot / Amazon Q Developer (for example CloudWatch alerts), and Hermes cannot see the actual alert/error content.
This is usually not a pure scope problem and not something a skill alone can fix.
The common failure mode is:
channels:history, groups:history, etc.)conversations.repliesbot_message / bot_id)attachments / blocks, not top-level textResult: the LLM never receives the actual alert body.
Hermes supports Slack bot ingress configuration:
slack:
allow_bots: all
Equivalent env var:
SLACK_ALLOW_BOTS=all
This only affects whether incoming Slack bot messages are accepted by the adapter.
Even with allow_bots: all, Hermes may still fail to read the root alert because:
_fetch_thread_context() still filters out bot-authored thread messagesmsg["text"]attachments / blocks are not converted into plain text contextSo if the user asks whether this can be solved by settings alone, the answer is usually no.
Primary Hermes files:
gateway/platforms/slack.pygateway/config.pywebsite/docs/user-guide/messaging/slack.mdtests/gateway/test_slack.pytests/gateway/test_slack_approval_buttons.pyInspect gateway/platforms/slack.py in _handle_slack_message().
Look for logic like:
event.get("bot_id")event.get("subtype") == "bot_message"allow_bots / SLACK_ALLOW_BOTSThis tells you whether Slack bot messages are accepted at ingress.
Inspect _fetch_thread_context() in gateway/platforms/slack.py.
Confirm it calls:
client.conversations_replies(channel=..., ts=...)Then check whether it discards messages with:
msg.get("bot_id")msg.get("subtype") == "bot_message"If yes, AWS Chatbot roots will be omitted from context.
Check whether thread context uses only:
msg.get("text", "")If so, alert bodies inside Slack attachments / blocks will be invisible.
Inspect gateway/config.py to verify that YAML config maps to env vars, e.g.:
slack.allow_bots -> SLACK_ALLOW_BOTSSearch the Hermes repo for these terms:
slack thread parentthread contextSLACK_ALLOW_BOTSconversations.repliesattachmentaws chatbotamazon qUseful issue categories:
In one investigation, these were relevant:
#1953 Slack bot doesn't fetch thread when mentioned#2950 Slack thread parent message missing from conversation context#3198 Add SLACK_ALLOW_BOTS#6345 Expose Slack history/thread reads as a toolIf no issue explicitly mentions AWS Chatbot / Amazon Q alert attachments, consider filing a new one because that is a narrower and more actionable bug.
Patch gateway/platforms/slack.py so thread-context fetch:
attachments and blocksAdd a helper such as:
_extract_slack_message_text(msg: dict) -> strIt should merge, normalize, and dedupe text from:
textattachments[].pretextattachments[].titleattachments[].textattachments[].fields[].title/valueattachments[].footerattachments[].fallbacksection, header, context, rich_text, image alt text)Do not confuse:
For this use case, Hermes does not need to auto-respond to every AWS Chatbot post. It only needs to read that content as context when a human later invokes Hermes in the thread.
So the safest behavior is:
Add regression tests for:
AWS Chatbot-like thread root
subtype="bot_message"attachmentstext empty or minimalOwn Hermes bot messages still excluded
Attachment-only messages
Human-only threads unchanged
Use these to prove which layer is affected:
source venv/bin/activate
# 1) Config/ingress effect: allow_bots changes whether inbound bot messages are processed
pytest tests/gateway/test_slack.py -k bot_messages_ignored -q
SLACK_ALLOW_BOTS=none pytest tests/gateway/test_slack.py -k bot_messages_ignored -q
# 2) Thread-context effect: even with allow_bots=all, fetched bot messages are still skipped
SLACK_ALLOW_BOTS=all pytest tests/gateway/test_slack_approval_buttons.py::TestSlackThreadContext::test_skips_bot_messages -q
pytest tests/gateway/test_slack_approval_buttons.py::TestSlackThreadContext::test_fetches_and_formats_context -q
Interpretation:
test_bot_messages_ignored fails under the current config but passes with SLACK_ALLOW_BOTS=none, the ingress setting is activetest_skips_bot_messages still passes, thread-context fetch still drops bot-authored messagesThis is the cleanest way to demonstrate that allow_bots affects inbound event acceptance but does not fix thread root ingestion.
Even after changing config and restarting the gateway, an existing Slack thread may still appear unchanged.
Why:
_fetch_thread_context() is only called when there is no active session for that threadSuspended 1 in-flight session(s) from previous run are evidence that the old thread session survivedPractical implication:
When asked whether permissions are enough:
slack.allow_bots: all is only a partial/workaround config, not the full fixWhen asked whether a skill can solve it:
Hermes uses two separate Slack config concepts. Confusing them causes alerts to be processed but never get a :white_check_mark:/:warning:/:rotating_light: reaction.
| Config key | Purpose | Drives reactions? |
|---|---|---|
slack.channel_skill_bindings | Auto-load a skill (e.g. check) when a message arrives in a channel | No |
slack.message_subscriptions | Tell the gateway "this bot message is an event we should react to and optionally reply to" | Yes |
If only channel_skill_bindings is set, the skill runs but the gateway
never adds the message ts to _reacting_message_ids.
on_processing_complete therefore exits early at the guard clause
ts not in self._reacting_message_ids and no emoji is posted.
Add a message_subscriptions entry for the Amazon Q bot:
slack:
allow_bots: all
message_subscriptions:
- channels: [C04KT7EH5RQ]
bot_names: ["Amazon Q Developer"]
reactions: true
bypass_mention: true
channel_skill_bindings:
- id: C04KT7EH5RQ
skills:
- check
Key fields:
channels or channel_ids — the monitored channel ID(s)bot_names or bot_ids — identity filter matching the Amazon Q bot
(check bot_profile.name in raw Slack events if unsure)reactions: true — opt this subscription into the reaction lifecyclebypass_mention: true — so the bot need not @-mention HermesAfter restarting the gateway, watch gateway.log for an incoming Amazon Q
message. You should see:
inbound message: platform=slack user=Amazon Q …Auto-loaded skill(s) line is required for reactions—the
subscription match happens before that—but the reactions flag on
the subscription is what populates _reacting_message_ids.response ready, the final emoji should appear on the original
Amazon Q message (not on Hermes's threaded reply).If the emoji still does not appear:
message_subscriptions is present in the active profile
config.yaml, not just channel_skill_bindings.SLACK_REACTIONS env var is set to false.reactions_add errors in gateway logs (missing
reactions:write scope, or the bot is not in the channel).Changing message_subscriptions requires a gateway restart because the
list is loaded once at startup via _slack_message_subscriptions().
A hermes config set or file edit alone is not enough.
Use this concise summary in future conversations:
If the Slack thread root comes from AWS Chatbot / Amazon Q, Hermes often misses it because the root is an external bot message and the real payload lives in attachments/blocks.
allow_bots: allcan relax ingress, but it does not by itself make Hermes include external bot thread roots or parse attachment content. That requires a patch ingateway/platforms/slack.py.Additionally, if reaction emojis are missing on Amazon Q alerts, check that
slack.message_subscriptionsis configured—not justchannel_skill_bindings—because the reaction lifecycle depends on the subscription match.