GitHub Actions github-script "Bad credentials" (Octokit)
actions/github-script builds an authenticated Octokit from the github-token input. If that token is empty, expired, or a malformed secret, the GitHub API returns HTTP 401 Bad credentials.
What this error means
A github-script step throws Bad credentials on the first API call, typically after passing a secret that is not set or a PAT that has expired.
github-actions
HttpError: Bad credentials
at /home/runner/work/_actions/actions/github-script/.../request-error.jsCommon causes
Empty or missing github-token
A referenced secret that is not configured resolves to an empty token.
Expired or wrong PAT
A personal access token that expired or lacks scope authenticates as bad credentials.
How to fix it
Pass a valid token
- Default to the built-in token: github-token: \${{ secrets.GITHUB_TOKEN }}.
- If using a PAT, confirm it is set as a secret and not expired.
- Verify the secret name matches exactly (case sensitive).
.github/workflows/ci.yml
- uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { data } = await github.rest.repos.get({
owner: context.repo.owner, repo: context.repo.repo });
core.info(data.full_name);How to prevent it
- Prefer GITHUB_TOKEN unless cross-repo access requires a PAT.
- Rotate PATs before expiry and store them as secrets.
Related guides
GitHub Actions default GITHUB_TOKEN is read-only (cannot push)Fix a GitHub Actions push that is denied - the default GITHUB_TOKEN is read-only and needs contents: write to…
GitHub Actions fromJSON "Unexpected end of JSON input"Fix GitHub Actions fromJSON "Unexpected end of JSON input" - fromJSON received an empty or truncated string.