The GH006 error occurs when GitHub's branch protection or repository rulesets require a specific workflow to pass before merging, but the workflow either failed, was skipped, or never ran. This commonly happens with CI/CD pipelines when pushing to protected branches or merging pull requests.
This error indicates that GitHub has blocked your push or merge operation because a required workflow did not complete successfully. GitHub uses branch protection rules and repository rulesets to enforce that specific GitHub Actions workflows must pass before code can be merged into protected branches. The error message "GH006: Required workflow 'ci.yml' did not complete successfully" tells you: 1. **GH006**: This is GitHub's error code for protected branch update failures 2. **Required workflow**: A workflow has been configured as mandatory in branch protection rules or organization rulesets 3. **Did not complete successfully**: The workflow either failed, was skipped, is still pending, or was never triggered This mechanism ensures code quality by requiring automated checks (like tests, linting, security scans) to pass before changes reach production branches. Organizations commonly use this to enforce CI/CD pipelines across all repositories. There are two main systems that can require workflows: 1. **Branch protection rules** (repository-level): Configured in repository settings under "Branches" > "Branch protection rules" 2. **Repository rulesets** (organization-level): Configured at the organization level and applied across multiple repositories. This is the newer, preferred method that replaced the legacy "required workflows" feature. When the required workflow doesn't complete as expected, GitHub prevents the merge to maintain code quality standards.
First, identify exactly which workflow failed and why. Look at the complete error output:
# Example error output:
remote: error: GH006: Protected branch update failed for refs/heads/main.
remote: error: Required workflow "CI Tests / build" did not complete successfully.
remote: error: pre-receive hook declinedThen check the workflow status on GitHub:
1. Go to your repository on GitHub
2. Click the Actions tab
3. Find the workflow run that corresponds to your push or PR
4. Check the status: Failed, Skipped, Pending, or Success
5. Click into the failed job to see detailed logs
If the workflow shows as Skipped or Pending, the issue is with workflow triggers. If it shows as Failed, check the job logs for the actual error.
If the workflow failed due to actual errors (tests, build, lint), fix those issues first:
# Run tests locally to identify failures
npm test
# or
pytest
# or
go test ./...
# Run linting locally
npm run lint
# or
flake8 .
# Fix any issues found, then commit and push
git add .
git commit -m "fix: resolve failing tests and linting issues"
git push origin your-branchCheck the workflow logs on GitHub for specific error messages:
1. Go to Actions tab
2. Click the failed workflow run
3. Expand the failed step to see the error output
4. Fix the underlying issue in your code
If the workflow was skipped, check if your workflow triggers are properly configured:
# .github/workflows/ci.yml
name: CI Tests
on:
# Trigger on pull requests to main
pull_request:
branches: [main, master]
# Required for merge queue support
merge_group:
types: [checks_requested]
# Trigger on pushes to main
push:
branches: [main, master]
# Avoid path filtering if the workflow is required
# paths:
# - 'src/**' # This can cause the workflow to be skipped!
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run tests
run: npm testImportant: If you use path filtering (paths:) and the workflow is required, it may be skipped when no matching files change. Either:
1. Remove path filtering from required workflows
2. Create a fallback workflow that passes when no changes match the path filter
The status check name must exactly match what's configured in branch protection. Check the naming:
For regular workflows:
jobs:
build: # This is the job name that appears as a status check
runs-on: ubuntu-latest
# ...The status check name will be: build
For reusable workflows:
jobs:
call-workflow:
uses: org/repo/.github/workflows/reusable.yml@mainThe status check name format is: <job name> / <reusable job name>
To check your branch protection settings:
1. Go to repository Settings > Branches
2. Click "Edit" on your branch protection rule
3. Look at "Require status checks to pass before merging"
4. Verify the check name matches your workflow's job name exactly
# List all status checks for a commit via GitHub CLI
gh api repos/{owner}/{repo}/commits/{sha}/statusIf you renamed a workflow file or job, update the branch protection rules:
1. Go to repository Settings > Branches
2. Click Edit on the protection rule for your branch
3. Under "Require status checks to pass before merging":
- Remove the old workflow/job name
- Add the new workflow/job name
4. Save changes
Common renaming issues:
# Before: .github/workflows/test.yml
name: Tests
jobs:
test:
# ...
# After: .github/workflows/ci.yml
name: CI Pipeline
jobs:
build-and-test: # Job name changed!
# ...The status check name changed from test to build-and-test. Update branch protection accordingly.
Note: For organization-level rulesets, you need organization admin access to modify the ruleset configuration.
If the required workflow is enforced via organization rulesets, check the ruleset configuration:
1. Go to your organization's Settings
2. Under "Code, planning, and automation", click Repository > Rulesets
3. Find the ruleset targeting your repository
4. Check the "Require workflows to pass" section
Key considerations for ruleset workflows:
# Ruleset workflows must support these events:
on:
pull_request:
pull_request_target:
merge_group:
# Other events like 'push' or 'workflow_dispatch' are ignoredVisibility requirements:
- Public workflows can run on any repository
- Internal workflows only run on internal and private repositories
- Private workflows only run on private repositories
If your workflow doesn't match the visibility requirements, it won't run.
Triggering workflow on existing PRs:
If a ruleset was added after your PR was opened, push a new commit to trigger the required workflow:
# Make a trivial change to trigger the workflow
git commit --allow-empty -m "chore: trigger CI workflow"
git push origin your-branchIf the branch is out of sync or status checks are stale, update your branch:
# Fetch latest changes from remote
git fetch origin
# If using strict status checks, rebase on the base branch
git checkout your-feature-branch
git rebase origin/main
# Or merge the base branch into your feature branch
git merge origin/main
# Push the updated branch
git push origin your-feature-branch --force-with-leaseFor pull requests via GitHub UI:
1. Go to your pull request
2. Click "Update branch" button (if available)
3. Choose "Update with merge commit" or "Update with rebase"
4. Wait for status checks to run again
Important: When "Require branches to be up to date before merging" is enabled (strict mode), you must update your branch with the latest base branch changes before the checks will pass.
If your repository uses GitHub merge queues, ensure your workflow supports the merge_group event:
name: CI
on:
pull_request:
branches: [main]
merge_group: # Required for merge queue support!
types: [checks_requested]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm testWithout the merge_group event:
- Status checks won't trigger when PRs enter the merge queue
- The merge will fail because required checks aren't reported
- You'll see "Required workflow did not complete" errors
After adding the event, the workflow will run both:
1. When a PR is opened/updated (pull_request event)
2. When the PR enters the merge queue (merge_group event)
If you need to bypass the required workflow (use sparingly):
Option 1: Repository ruleset bypass list
If using organization rulesets, ask an admin to add you to the bypass list:
1. Organization Settings > Repository > Rulesets
2. Edit the relevant ruleset
3. Add your user/team to the bypass list
4. Use bypass only for emergencies with proper documentation
Option 2: Branch protection bypass
For repository-level branch protection:
1. Repository Settings > Branches
2. Edit the branch protection rule
3. Enable "Allow specified actors to bypass required pull requests"
4. Add yourself or your team
Option 3: Temporarily disable the rule
As a last resort, an admin can temporarily disable the rule:
# If you have admin access, use GitHub CLI
gh api -X PATCH repos/{owner}/{repo}/branches/main/protection/required_status_checks \
-f strict=false \
-f contexts[]=""Warning: Bypassing required workflows should be rare and documented. It defeats the purpose of having quality gates.
### Understanding GitHub's Required Workflow Systems
GitHub has two distinct systems for requiring workflows:
1. Branch Protection Rules (Repository-level)
- Configured per-repository in Settings > Branches
- Uses status checks from any GitHub Actions workflow
- Can specify which GitHub App must provide the status
- Simpler to set up for individual repositories
2. Repository Rulesets (Organization-level)
- Configured at organization level, applied to multiple repos
- Can require specific workflow files to run and pass
- Supports evaluation mode for testing rules
- More powerful but requires organization admin access
- Replaced the legacy "Required Workflows" feature
### Status Check Naming Conventions
Understanding how status check names are formed is crucial:
| Workflow Type | Status Check Name Format |
|---------------|-------------------------|
| Regular job | <job_name> |
| Matrix job | <job_name> (<matrix_values>) |
| Reusable workflow | <calling_job> / <reusable_job> |
| External CI | <check_name> (as reported by the service) |
Example for matrix builds:
jobs:
test:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}This creates two status checks:
- test (ubuntu-latest)
- test (windows-latest)
### Dealing with Skipped Workflows
When workflows are skipped due to path filters:
Problem: Branch protection requires the check, but it never runs.
Solution 1: Remove path filtering
on:
pull_request:
branches: [main]
# Remove paths to ensure workflow always runsSolution 2: Create a fallback workflow
# .github/workflows/ci-fallback.yml
name: CI Tests # Same name as the main workflow
on:
pull_request:
branches: [main]
paths-ignore:
- 'src/**' # Inverse of main workflow paths
jobs:
build: # Same job name
runs-on: ubuntu-latest
steps:
- run: echo "No relevant changes, skipping tests"### Debugging with GitHub CLI
# Check branch protection rules
gh api repos/{owner}/{repo}/branches/main/protection
# List required status checks
gh api repos/{owner}/{repo}/branches/main/protection/required_status_checks
# View commit statuses
gh api repos/{owner}/{repo}/commits/{sha}/status
# View check runs for a commit
gh api repos/{owner}/{repo}/commits/{sha}/check-runs
# List organization rulesets
gh api orgs/{org}/rulesets### Common Failure Patterns
| Error Pattern | Likely Cause | Solution |
|---------------|--------------|----------|
| "Required workflow has not completed" | Workflow never triggered | Check triggers and path filters |
| "Required status check 'X' is failing" | Workflow failed | Fix failing tests/build |
| "Required status check 'X' is expected" | Wrong check name | Match job name to protection config |
| "Was not set by the expected GitHub App" | Wrong status source | Check GitHub App configuration |
| Workflow stuck on "Pending" | Skipped due to filters | Update workflow triggers |
### Using Personal Access Tokens for Automation
If GitHub Actions needs to push to protected branches:
# Use a PAT or GitHub App token instead of GITHUB_TOKEN
- uses: actions/checkout@v4
with:
token: ${{ secrets.PAT_TOKEN }}
- name: Commit changes
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git commit -am "chore: automated update"
git pushThe bot user or GitHub App must be added to the bypass list in branch protection settings.
### Ruleset Evaluation Mode
Before enforcing a new ruleset, test it in evaluation mode:
1. Create the ruleset with enforcement status "Evaluate"
2. Monitor the audit log for rule evaluations
3. Check that the workflow runs correctly on test PRs
4. Once confident, change enforcement to "Active"
This prevents accidentally blocking all merges when configuring new rules.
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