Skip to content

fix(ci): issue titles containing quotes break the Slack notification workflow#1107

Open
Echolonius wants to merge 1 commit into
anthropics:mainfrom
Echolonius:fix/slack-notification-title-escaping
Open

fix(ci): issue titles containing quotes break the Slack notification workflow#1107
Echolonius wants to merge 1 commit into
anthropics:mainfrom
Echolonius:fix/slack-notification-title-escaping

Conversation

@Echolonius

Copy link
Copy Markdown

Problem

The "Post new issues to Slack" workflow interpolates the raw issue title into its JSON payload:

"text": "*New Issue:* <${{ github.event.issue.html_url }}|#${{ github.event.issue.number }} ${{ github.event.issue.title }}>"

Any issue title containing a double quote produces invalid JSON, and the run fails. The correlation is exact across this workflow's history:

Run Issue title Conclusion
2026-07-11 … ("Error: Stream closed") (#1105) ❌ failure
2026-06-18 PreToolUse "defer" does not end the query (#1060) ❌ failure
2026-06-15 … with skills="all" … (#1044) ❌ failure
all others quote-free titles ✅ success

Beyond lost notifications, the raw interpolation lets a crafted title inject arbitrary JSON into the chat.postMessage payload (e.g. extra Slack API fields/blocks).

Fix

Wrap the interpolation in toJSON(format(...)), which emits a fully-escaped JSON string (quotes, backslashes, newlines).

Verified by parsing the workflow YAML and simulating the expression interpolation with a hostile title (quotes + backslashes): the rendered payload is valid JSON and the title displays verbatim.

🤖 Generated with Claude Code

https://claude.ai/code/session_01YcMi8ny9DUBDf6y6m76HWk

The workflow interpolated the raw issue title into a JSON payload, so
any title containing a double quote produced invalid JSON and the run
failed. All three historical failures of this workflow (issues titled
with "defer", skills="all", and "Error: Stream closed") are titles
containing quotes; every success is quote-free.

Wrap the interpolation in toJSON(format(...)) so the title is escaped
(and, as a side effect, a crafted title can no longer inject arbitrary
Slack API payload fields).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant