This error occurs when a GitHub Actions workflow uses an action that requires a 'token' input but none was provided. The fix typically involves explicitly passing the GITHUB_TOKEN secret or ensuring your workflow has the correct permissions configured.
This error indicates that a GitHub Actions workflow step is trying to use an action that expects a `token` input parameter, but that parameter was not provided in the workflow configuration. Many GitHub Actions, particularly those that interact with the GitHub API (such as checkout actions, PR comment actions, issue management actions, and deployment actions), require authentication via a token to perform operations on your repository. Without this token, the action cannot authenticate and fails immediately. The most common actions that require a token include: - `actions/checkout` (for private repositories or when pushing commits) - `peter-evans/create-pull-request` - `actions/github-script` - `thollander/actions-comment-pull-request` - Custom composite actions that call the GitHub API The `GITHUB_TOKEN` is automatically generated for each workflow run and provides scoped access to the repository. However, some actions require you to explicitly pass this token as an input rather than relying on automatic authentication.
The most common fix is to explicitly pass the GITHUB_TOKEN to the action that requires it:
- name: Checkout repository
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}For actions that interact with pull requests or issues:
- name: Comment on PR
uses: thollander/actions-comment-pull-request@v2
with:
message: "Build successful!"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}Some actions use different parameter names for the token. Check the action's documentation:
# Some actions use 'github-token'
- uses: some-action/example@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
# Others use 'repo-token'
- uses: another-action/example@v1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}Action requirements can change between versions. Always verify the required inputs for the version you're using:
Find the action's repository:
1. The action name format is owner/repo@version
2. Go to github.com/owner/repo
3. Check the action.yml file for required inputs
Example: Checking action.yml:
# In the action's action.yml file:
inputs:
token:
description: 'GitHub token for authentication'
required: true # <-- This means you MUST provide it
default: ''Common actions and their token parameters:
| Action | Token Parameter |
|--------|----------------|
| actions/checkout | token |
| actions/github-script | github-token |
| peter-evans/create-pull-request | token |
| actions/create-release | token |
| softprops/action-gh-release | token |
Always check the README or action.yml of the specific version you're using.
GitHub Actions has a permissions system that controls what the GITHUB_TOKEN can do. Ensure your workflow has the required permissions:
Add permissions at the job level:
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
issues: write
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}Or at the workflow level:
name: CI
on: [push, pull_request]
permissions:
contents: read
pull-requests: write
jobs:
build:
runs-on: ubuntu-latest
# ...Common permission scopes:
- contents: read - Read repository contents
- contents: write - Push commits, create branches
- pull-requests: write - Comment on PRs, add labels
- issues: write - Create/modify issues
- packages: write - Publish packages
- deployments: write - Create deployments
Check repository settings:
1. Go to Repository Settings > Actions > General
2. Under "Workflow permissions", ensure appropriate access
3. If "Read repository contents and packages permissions" is selected, you may need to add explicit permissions
When a workflow runs on a pull request from a fork, the GITHUB_TOKEN has restricted permissions for security reasons:
The problem:
- Fork PRs have read-only GITHUB_TOKEN by default
- Actions that need write access will fail
Solutions:
1. Use `pull_request_target` for trusted operations:
on:
pull_request_target:
types: [opened, synchronize]
jobs:
comment:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
# IMPORTANT: Check out PR head for pull_request_target
ref: ${{ github.event.pull_request.head.sha }}
token: ${{ secrets.GITHUB_TOKEN }}Warning: pull_request_target runs in the context of the base repository. Never run untrusted code from the PR in this context.
2. Use a two-workflow approach:
# Workflow 1: Build (runs on PR, limited permissions)
name: Build
on: pull_request
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm test
- uses: actions/upload-artifact@v4
with:
name: results
path: results.json
# Workflow 2: Comment (runs after build, full permissions)
name: Comment
on:
workflow_run:
workflows: ["Build"]
types: [completed]
jobs:
comment:
runs-on: ubuntu-latest
permissions:
pull-requests: write
# Use workflow_run context to comment with full permissionsIf the default GITHUB_TOKEN doesn't have sufficient permissions (e.g., triggering other workflows, accessing other repositories), use a Personal Access Token (PAT):
Step 1: Create a PAT:
1. Go to GitHub Settings > Developer settings > Personal access tokens
2. Click "Generate new token (classic)" or "Fine-grained tokens"
3. Select required scopes:
- repo - Full repository access
- workflow - Update GitHub Action workflows
4. Generate and copy the token
Step 2: Add PAT as a repository secret:
1. Go to Repository Settings > Secrets and variables > Actions
2. Click "New repository secret"
3. Name it (e.g., PAT_TOKEN) and paste the token value
Step 3: Use the PAT in your workflow:
- name: Checkout with PAT
uses: actions/checkout@v4
with:
token: ${{ secrets.PAT_TOKEN }}
- name: Create PR
uses: peter-evans/create-pull-request@v5
with:
token: ${{ secrets.PAT_TOKEN }}
title: "Automated PR"
branch: auto-updateWhen to use PAT vs GITHUB_TOKEN:
- Use GITHUB_TOKEN for most operations (it's automatically rotated and scoped)
- Use PAT when you need to:
- Trigger other workflows
- Access other repositories
- Perform operations across organization
- Work around fork restrictions
If you're still having issues, use these debugging techniques:
Print available context (for debugging only):
- name: Debug info
run: |
echo "Event: ${{ github.event_name }}"
echo "Actor: ${{ github.actor }}"
echo "Repository: ${{ github.repository }}"
echo "Token permissions available:"
echo "${{ toJson(github.token) }}" | head -c 20
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}Check if token is being passed:
- name: Verify token exists
run: |
if [ -z "$TOKEN" ]; then
echo "ERROR: Token is empty!"
exit 1
else
echo "Token is set (length: ${#TOKEN})"
fi
env:
TOKEN: ${{ secrets.GITHUB_TOKEN }}Test GitHub API access:
- name: Test API access
run: |
curl -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/repos/${{ github.repository }}Check effective permissions:
- name: Check token permissions
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { data } = await github.rest.apps.getRepoInstallation({
owner: context.repo.owner,
repo: context.repo.repo,
});
console.log('Permissions:', data.permissions);Token handling can change between action versions. Ensure you're using compatible versions:
Pin to specific versions:
# Good: Pin to major version (gets security updates)
- uses: actions/checkout@v4
# Better for stability: Pin to specific version
- uses: actions/[email protected]
# Most stable: Pin to commit SHA
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11Check for breaking changes:
1. Visit the action's releases page
2. Read CHANGELOG or release notes for your version
3. Look for migration guides between major versions
Example: actions/checkout v3 to v4:
# v3 - token was optional for public repos
- uses: actions/checkout@v3
# v4 - may require explicit token in some cases
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}Update action versions safely:
# Use dependabot or renovate to track action updates
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"### Understanding GITHUB_TOKEN Permissions Model
The GITHUB_TOKEN has different permission levels depending on the context:
Default permissions (configurable at repo/org level):
- Read access to contents
- Write access to packages
- Limited access to other resources
Permission inheritance:
1. Organization default settings
2. Repository settings override
3. Workflow-level permissions override
4. Job-level permissions override (most specific)
Checking organization defaults:
Organization owners can set default token permissions at Settings > Actions > General > Workflow permissions.
### Composite Actions and Token Passing
If you're using or creating composite actions, tokens need to be passed through explicitly:
# In composite action's action.yml
inputs:
token:
description: 'GitHub token'
required: true
runs:
using: composite
steps:
- uses: actions/checkout@v4
with:
token: ${{ inputs.token }}# In calling workflow
- uses: your-org/your-composite-action@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}### Reusable Workflows and Secrets
For reusable workflows, tokens must be passed explicitly:
# Reusable workflow (.github/workflows/reusable.yml)
on:
workflow_call:
secrets:
token:
required: true
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.token }}# Calling workflow
jobs:
call-reusable:
uses: ./.github/workflows/reusable.yml
secrets:
token: ${{ secrets.GITHUB_TOKEN }}### GitHub Apps vs Personal Access Tokens
For more granular control and better security, consider using GitHub App tokens:
- name: Generate GitHub App token
id: generate-token
uses: tibdex/github-app-token@v2
with:
app_id: ${{ secrets.APP_ID }}
private_key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Use app token
uses: actions/checkout@v4
with:
token: ${{ steps.generate-token.outputs.token }}Benefits of GitHub Apps:
- Fine-grained permissions
- Higher rate limits
- Better audit trail
- Can be shared across repositories
- Not tied to a personal account
### Environment Protection Rules
If your workflow uses environments with protection rules, token permissions might be restricted:
jobs:
deploy:
runs-on: ubuntu-latest
environment: production # May have required reviewers
permissions:
contents: read
deployments: write
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}### Troubleshooting Specific Actions
actions/checkout:
- For private submodules, use PAT with repo scope
- For pushing commits back, need contents: write
peter-evans/create-pull-request:
- Needs contents: write and pull-requests: write
- Won't trigger workflows unless using PAT
softprops/action-gh-release:
- Needs contents: write permission
- Token is optional for public repos but recommended
kex_exchange_identification: Connection closed by remote host
Connection closed by remote host when connecting to Git server
fatal: unable to access: Proxy auto-configuration failed
How to fix 'Proxy auto-configuration failed' in Git
fatal: unable to access: Authentication failed (proxy requires basic auth)
How to fix 'Authentication failed (proxy requires basic auth)' in Git
fatal: unable to access: no_proxy configuration not working
How to fix 'no_proxy configuration not working' in Git
fatal: unable to read tree object in treeless clone
How to fix 'unable to read tree object in treeless clone' in Git