Skip to content

fix: handle 404 errors in checkWritePermissions for non-user actors#1030

Open
MaxwellCalkin wants to merge 1 commit into
anthropics:mainfrom
MaxwellCalkin:fix/check-write-permissions-non-user-404
Open

fix: handle 404 errors in checkWritePermissions for non-user actors#1030
MaxwellCalkin wants to merge 1 commit into
anthropics:mainfrom
MaxwellCalkin:fix/check-write-permissions-non-user-404

Conversation

@MaxwellCalkin

Copy link
Copy Markdown
Contributor

Summary

Fixes #1018

checkWritePermissions calls octokit.repos.getCollaboratorPermissionLevel() with github.actor as the username. When the actor is a non-user entity like Copilot (from a Copilot-initiated pull_request_review), this API returns a 404 because Copilot is not a regular GitHub user.

The existing bot bypass only checks for actors ending in [bot], but Copilot does not follow that naming convention.

Changes

  • src/github/validation/permissions.ts: Added 404 error handling in the catch block. When the collaborator permissions API returns a 404 (indicating the actor is not a GitHub user), the function now logs an informational message and returns true instead of throwing. Non-404 errors continue to throw as before.

  • test/permissions.test.ts: Added 4 new test cases:

    • 404 from API for Copilot actor returns true
    • 404 from API for any non-user actor name returns true
    • Non-404 errors (e.g., generic Error) still throw
    • 500 server errors still throw

Why this approach

Rather than maintaining a hardcoded list of non-user actor names (which would need updating as GitHub adds new system actors), this fix catches the 404 response that GitHub already returns when an actor is not a user. This is robust against future non-user actors being added by GitHub.

This is consistent with how other parts of the codebase handle 404s from GitHub APIs (e.g., branch-cleanup.ts, update-claude-comment.ts).

Test plan

  • All 17 permissions tests pass (including 4 new ones)
  • Full test suite passes (19 pre-existing Windows-specific failures unrelated to this change)
  • Verify with a Copilot-triggered pull_request_review workflow

The collaborator permissions API returns 404 for actors like "Copilot"
that are not regular GitHub users. Previously, only actors ending in
"[bot]" were bypassed, causing workflows triggered by Copilot reviews
to fail with "Copilot is not a user" errors.

This adds 404 error handling in the catch block so that non-user actors
are recognized and allowed through, matching the existing behavior for
[bot] actors.

Fixes anthropics#1018

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
maxbec added a commit to navigaite/.github that referenced this pull request Apr 18, 2026
## Summary

Copilot PR reviews have been silently failing claude-code-action@v1 —
its `checkHumanActor` step calls
`octokit.users.getByUsername('Copilot')`, which 404s because `Copilot`
is a virtual actor with no user record. No action input bypasses that
lookup (upstream PRs
[#1018](anthropics/claude-code-action#1018),
[#1030](anthropics/claude-code-action#1030),
[#1144](anthropics/claude-code-action#1144) are
all still open).

Observed on [navigaite/edilio#94 run
24551381827](https://github.com/navigaite/edilio/actions/runs/24551381827/job/71777721521):

```
Checking permissions for actor: Copilot
GET /users/Copilot - 404
Action failed with error: Not Found
```

## Fix

Proxy Copilot reviews into an `issue_comment` event that Claude's
existing pipeline can handle:

- **New `repost-copilot-review` job** in the reusable
`claude-code.yaml`. Fires only when `pull_request_review.user.type ==
'Bot'` and login contains `copilot`. Mints the Navigaite workflow App
token, fetches the review's inline comments via `GET
/pulls/:n/reviews/:id/comments`, and posts a single stitched `@claude …`
comment on the PR.
- **Skip the `claude` job on Copilot reviews** — it would hit the 404.
The spawned `issue_comment` re-enters the job with `github.actor ==
'navigaite-workflow-app[bot]'`, a real bot user that resolves, so
`checkHumanActor`'s `allowed_bots: *` branch takes over.
- **Relax the `issue_comment` author-association gate** (both the
reusable workflow step and the caller template's `if:`) to admit
comments from `navigaite-workflow-app[bot]`. Reposted comments have
`author_association: NONE` by construction — trust is anchored in the
fact that only our installed app can mint its own token.

## Test plan

- [ ] Merge, re-request Copilot review on an open PR in a consumer repo,
confirm: (1) `repost-copilot-review` job succeeds, (2) an `@claude …`
comment appears on the PR, (3) a follow-up `issue_comment` run of the
`claude` job runs to completion without the `users/Copilot` 404.
- [ ] Confirm human `@claude` comments still trigger Claude normally
(unchanged path).
- [ ] Confirm unrelated bot comments (Dependabot, github-actions) are
still filtered out by the association gate.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

checkWritePermissions fails with 404 for non-user actors like Copilot

1 participant