Inline-comment buffer uses a fixed /tmp path that leaks comments across runs (and repos) on self-hosted runners
Summary
src/entrypoints/post-buffered-inline-comments.ts reads buffered inline comments from a fixed, machine-wide path:
const BUFFER_PATH = "/tmp/inline-comments-buffer.jsonl";and (as far as we can tell) the file is not deleted after posting. On GitHub-hosted runners this is invisible because the VM is ephemeral. On self-hosted runners it causes cross-run — and, when multiple repos share a runner host, cross-repo — comment leakage.
What we observed
On an org with several private repos sharing self-hosted runners:
- A review run in repo B produced a clean structured verdict with zero issues and no inline-comment tool calls.
- Its 'Post buffered inline comments' step nonetheless reported
Found 9 buffered inline comment(s)and attempted to post comments referencing repo A's files (queued there by an earlier review of repo A on the same machine) onto repo B's PR. - All posts failed with 422
pull_request_review_thread.path could not be resolved— GitHub's path validation was the only thing that prevented one repo's (private) review comments from landing on another repo's PR — and the step's failure made an otherwise-clean review check fail. - With
ANTHROPIC_API_KEYunset (OAuth-token setups), the poster logsskipping classification, posting all unconfirmed comments, which maximizes the blast radius.
Note the privacy angle in (3): buffered comment bodies can contain file paths and code excerpts from a different repository; only the 422 stopped them from being published to the wrong PR.
Suggested fix
- Scope the buffer per run: e.g.
${RUNNER_TEMP}/inline-comments-buffer-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}.jsonl(both available to the MCP server and the poster), or at minimum includeGITHUB_REPOSITORY+PR number in the filename and validate on read. - Delete (or truncate) the buffer in the poster after a flush, success or failure.
Our workaround meanwhile: rm -f /tmp/inline-comments-buffer.jsonl immediately before the action step and again in an always() cleanup step.
Happy to open a PR for the RUNNER_TEMP scoping if that direction sounds right.
Source: anthropics/claude-code-action