Skip to main content
All failure patterns
Dependency or configurationGitHub Actions · CI

GitHub Actions: Resource not accessible by integration: Resource not accessible by integration

A GitHub API call made with the workflow's GITHUB_TOKEN, or with a GitHub App token, returned 403 because that token does not hold the permission the endpoint needs. Posting PR comments, adding labels and creating releases are the usual places it appears.

MINIMAL REPRO

Reproduce it

Run on 2026-10-23 with actions/github-script@v9, GitHub Actions runner 2.338.1. The output below is what it printed.

.github/workflows/comment.yml
on: pull_request
permissions:
  contents: read
jobs:
  comment:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/github-script@v9
        with:
          script: |
            await github.rest.issues.createComment({
              ...context.repo,
              issue_number: context.issue.number,
              body: "Report attached",
            })
command
Open a pull request against the repository.
output
GITHUB_TOKEN Permissions
  Contents: read
  Metadata: read
Run actions/github-script@v9
Error: Unhandled error: HttpError: Resource not accessible by integration - https://docs.github.com/rest/issues/comments#create-an-issue-comment
RequestError [HttpError]: Resource not accessible by integration - https://docs.github.com/rest/issues/comments#create-an-issue-comment
  status: 403,
  response: {
    headers: {
      'x-accepted-github-permissions': 'issues=write; pull_requests=write',

# The stack trace and the other response headers are trimmed.

RANKED DIAGNOSIS

What usually causes it

  1. 01

    A permissions block left the needed scope out

    Once a workflow or job sets permissions, every permission it does not list is set to none. The repro asks only for contents: read, so the comment call has neither issues nor pull-requests write. GitHub's REST reference lists Issues (write) or Pull requests (write) for Create an issue comment.

    DIAGNOSE

    Look up the endpoint in the REST reference, or read the X-Accepted-GitHub-Permissions response header, which names the permissions it accepts. Then compare with the job's permissions block.

    FIX

    Add the narrowest permission the endpoint lists (here `pull-requests: write`) at job level, not write-all at workflow level.

  2. 02

    The run came from a fork or from Dependabot

    For pull request events other than pull_request_target from a fork, GitHub turns every write permission into read unless an admin enabled Send write tokens to workflows from pull requests. Dependabot runs are treated the same way. The permissions key cannot grant write here.

    DIAGNOSE

    Check whether the failing run's head repository differs from the base, or whether the actor is dependabot[bot]. The same workflow passing on a branch in the base repository confirms it.

    FIX

    Split the work: the pull_request workflow computes the result and uploads it as an artifact; a workflow_run workflow in the base repository posts it, treating the artifact as untrusted data. Do not move it to pull_request_target casually: GitHub's default policy starts blocking that event in public repositories on November 2, 2026.

  3. 03

    The repository or organization default is restricted

    The token starts from the enterprise, organization or repository default. If that default is the restricted one, a workflow without a permissions block gets read-only contents and packages, and anything that writes fails.

    DIAGNOSE

    Check Settings, Actions, General, Workflow permissions for the repository and its organization.

    FIX

    Leave the restricted default in place and grant the one write permission in the job that needs it.

  4. 04

    GITHUB_TOKEN cannot do this at all

    GITHUB_TOKEN is scoped to the repository running the workflow. Writing to another repository, or to organization-level resources, needs a GitHub App installation token or another credential with that access.

    DIAGNOSE

    If the call targets a different owner or repository than github.repository, this is the cause.

    FIX

    Use a GitHub App installation token scoped to the target repository, created in the job that needs it.

VERIFIED FIX

The fix, and how it was checked

Grant the single permission the endpoint names, in the job that calls it.

.github/workflows/comment.yml (job)
jobs:
  comment:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: write

Run on 2026-10-23 as two jobs in one workflow, on a pull request from a branch in the same repository: the job with only contents: read failed with the 403 above, and the response's x-accepted-github-permissions header named issues=write; pull_requests=write. A second job with pull-requests: write added, and nothing else changed, logged PullRequests: write under GITHUB_TOKEN Permissions and posted its comment as github-actions[bot]. The fork case was not run; it follows GitHub's GITHUB_TOKEN reference.

When this is not the cause

A wrong or expired token
Invalid credentials get 401 with Bad credentials, not 403. We checked: a request to api.github.com/user with a made-up bearer token returned {"message": "Bad credentials", "status": "401"}.
write-all fixes fork runs
It does not. For fork pull requests the write permissions are downgraded after the workflow's own settings are applied, whatever the workflow asks for.
The personal access token variant
Resource not accessible by personal access token is the same check for a fine-grained PAT. The fix is on the token's settings page, not in the workflow's permissions block.

Prevent the repeat

  • →Set permissions per job and start from contents: read.
  • →Design anything that writes back to a PR to work from forks: pull_request plus workflow_run.
  • →Review permission changes in workflow files like code.

Primary references

Run this against your evidence

The browser triage workflow uses the same stable pattern slug and does not upload your paste.

Open local triage

Related failure patterns