Skip to content
LatchkeyLatchkey home

GitHub Actions "Resource not accessible" Setting a Commit Status

A step that sets a commit status (a custom context shown on the commit and PR) fails with a 403 because the workflow token lacks statuses: write.

What this error means

A call to create a commit status returns "Resource not accessible by integration", so the custom status context never appears on the commit or pull request.

Actions log
Error: Resource not accessible by integration
  status: 403
  POST /repos/org/repo/statuses/{sha}

Diagnose it: what token do you actually have?

Permission failures in Actions are almost never about your repository settings alone. Three things combine: the default GITHUB_TOKEN permission set for the repo or organization, the permissions: block in the workflow, and whether the event is a fork pull request, which downgrades the token to read-only regardless of everything else.

.github/workflows/ci.yml
- name: Show the token scopes actually granted
  run: |
    curl -sI -H "Authorization: Bearer $GITHUB_TOKEN" \
      https://api.github.com/ | grep -i "^x-oauth-scopes\|^x-accepted"
    echo "event: ${{ github.event_name }}"
    echo "fork PR: ${{ github.event.pull_request.head.repo.fork }}"
  env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Common causes

Missing statuses: write permission

Creating commit statuses requires statuses: write. It is not granted under restricted default permissions, so the call is denied.

Confusing statuses with checks

The Statuses API and the Checks API are different. Granting checks: write does not enable the statuses endpoint, and vice versa.

How to fix it

Grant statuses: write

.github/workflows/ci.yml
permissions:
  contents: read
  statuses: write
jobs:
  report:
    runs-on: ubuntu-latest

Grant the right scope for the API you use

  1. Use statuses: write for the commit Statuses API.
  2. Use checks: write for the Checks API (check runs and annotations).
  3. Scope the permission to the job that writes the status.

Grant the narrowest permission that works

Declaring a permissions: block switches the job from the repository default to exactly what you list, so an incomplete block is a common cause of a new failure right after someone tightened security. List every scope the job needs, not just the one that failed.

.github/workflows/ci.yml
permissions:
  contents: read        # checkout
  packages: write       # push to GHCR
  id-token: write       # OIDC to a cloud provider
  pull-requests: write  # comment on or label a PR
  checks: write         # publish check runs

How to prevent it

  • Match the permission scope to the exact API the step calls.
  • Grant statuses: write only on the reporting job.
  • Keep default workflow permissions read-only and opt in per job.

Frequently asked questions

What causes GitHub Actions "Resource not accessible" setting a commit status?
There are 2 common causes: missing statuses: write permission and confusing statuses with checks. Creating commit statuses requires statuses: write.
How do I fix GitHub Actions "Resource not accessible" setting a commit status?
There are 2 fixes depending on which cause you have: grant statuses: write and grant the right scope for the api you use. Work through them in order, since the first is the most common.
What does GitHub Actions "Resource not accessible" setting a commit status actually mean?
A call to create a commit status returns "Resource not accessible by integration", so the custom status context never appears on the commit or pull request.
How do I stop GitHub Actions "Resource not accessible" setting a commit status happening again?
Match the permission scope to the exact API the step calls. The prevention section lists 3 changes that keep it from recurring.

Related guides

References

Not every red build is your code. Latchkey repairs the ones that are not, on the runner. Start free → 30-day trial · No credit card