anthropics / anthropics/claude-code-action
Agent mode discards session summary: cleanup phase gates updateCommentLink on commentId, agent mode hard-codes commentId: undefined
- Dominant language
- TypeScript
- Stars
- 8.9k
- Forks
- 2.1k
- Avg merge
- 3d 9h
- Merged PRs (30d)
- 10
Description
## Summary
When the action runs in agent mode (`prompt:` set, no `@claude` trigger), the session summary the SDK emits never reaches GitHub. The Claude session runs to completion, generates a review, and the output is discarded at action cleanup.
Verified on `v1` (action built from `v1.0` tag per `action.yml`).
## Observed behavior
Workflow config (our `.github/workflows/claude-code-review.yml` — automated PR-review workflow):
```yaml
on:
pull_request:
types: [opened, synchronize]
jobs:
claude-review:
# ...
steps:
- uses: actions/checkout@v4
- uses: anthropics/claude-code-action@v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
classify_inline_comments: "false"
prompt: |
Review this PR. Report blockers, should-fixes, and nits.
If clean, say "no blockers found" plainly.
```
Across 7 PRs on our repo over two days (N=7):
- 5 clean PRs (docs-only, small code, tests, etc.): **silent.** Zero bot output on any of `pulls//reviews`, `issues//comments`, `pulls//comments`. Session succeeded (`subtype: "success"`, `is_error: false`), turn count 15–22, cost $0.23–$0.49 per run. No error anywhere.
- 1 PR with a hard-blocker pattern (deliberate `throw`): posted 3 inline findings as a review. Summary text still not present.
- 1 PR with `show_full_output: "true"` enabled: revealed the SDK's final assistant text event contained a complete 1098-character clean-PR review ending `"No blockers found. This is a clean docs-only change."` — emitted 117ms before `"type": "result"`. Nothing reached GitHub.
## Root cause (source reading at `ref=v1`)
`src/entrypoints/run.ts` cleanup phase (~line 244 in current `v1`):
```typescript
if (commentId && context && isEntityContext(context) && githubToken && octokit) {
try {
await updateCommentLink({
commentId, ..., outputFile: executionFile, ...
});
} catch (error) {
console.error("Error updating comment with job link:", error);
}
}
```
`updateCommentLink` is the function that reads `executionFile` (where the SDK wrote the summary), formats it, and updates a GitHub comment with it. It only runs if `commentId` is truthy.
`src/modes/agent/index.ts` (end of `prepareAgentMode`):
```typescript
return {
commentId: undefined, // No tracking comment in agent mode
branchInfo: { ... },
mcpConfig: ourMcpConfig,
claudeArgs,
};
```
Agent mode explicitly returns `commentId: undefined`. Cleanup sees falsy → skips `updateCommentLink` → summary never published.
`src/modes/tag/index.ts:prepareTagMode` doesn't have this issue — it calls `createInitialComment(octokit.rest, context)` up front, captures `commentData.id`, and the tracking comment becomes the summary destination.
## Inline comments are not affected
`src/entrypoints/post-buffered-inline-comments.ts` reads `/tmp/inline-comments-buffer.jsonl` and posts independently of `commentId`. When the session uses the inline-comment MCP tool (hard-blocker patterns trigger this), those findings do post. The summary does not.
## Current workaround
`track_progress: "true"` forces tag mode even when `prompt:` is set (per `src/modes/detector.ts:18–29`), which flows commentId correctly. Verified working on our repo — tracking comment appears at session start and gets rewritten with the 1413-character final review 71 seconds later.
Side effect: a transient "Claude is working on this…" placeholder comment appears before the rewrite. That's fine for short sessions but isn't ideal for the automation-review use case where users just want the final output.
## Feature request
A documented option for "post the final summary to the PR even in agent mode, without the tracking-comment dance." Something like:
```yaml
post_summary: "always" # or post_summary_on_clean: "true"
```
Or equivalently: a config that makes agent mode create a lightweight summary-only comment at cleanup (not a tracking comment at start) if one doesn't already exist.
Either way, the underlying fix is narrow: in `run.ts` cleanup, when in agent mode with an `executionFile` that has extractable summary content, post it to `issues//comments` as a new comment rather than silently discarding it.
## Why this matters for review automation
PR-review workflows are a natural fit for agent mode (one prompt, run on every push, no @claude trigger ceremony). The silent-on-clean default surprises maintainers who expected "clean PR → short 'no blockers' summary" and got nothing. It also breaks cross-check patterns where the reviewing human depends on being able to observe bot findings alongside their own.
Happy to open a PR if the approach makes sense to you — the fix is small and localized to `run.ts` and `agent/index.ts`. Let me know.
Contributor guide
Research direction
Start with the cleanup phase in src/entrypoints/run.ts and prepareAgentMode in src/modes/agent/index.ts, then compare prepareTagMode in src/modes/tag/index.ts. Trace how executionFile and commentId are handled, and verify that an agent-mode session publishes its final summary to the PR without requiring a tracking comment while inline comments continue to work.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- github, typescript
- Domain
- ci-cd, devtools
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 56/100