GitHub Agentic Workflows

Common Issues

Frequently encountered issues, organized by workflow stage and component.

If gh extension install github/gh-aw fails, use the standalone installer (works in Codespaces and restricted networks). Pass a tag as the second argument to pin a version (releases). Verify with gh extension list.

Terminal window
curl -sL https://raw.githubusercontent.com/github/gh-aw/main/install-gh-aw.sh | bash
curl -sL https://raw.githubusercontent.com/github/gh-aw/main/install-gh-aw.sh | bash -s -- v0.40.0

Custom Actions Not Allowed in Enterprise Organizations

Section titled “Custom Actions Not Allowed in Enterprise Organizations”

Error: The action github/gh-aw/actions/setup@... is not allowed in {ORG} because all actions must be from a repository owned by your enterprise, created by GitHub, or verified in the GitHub Marketplace.

Cause: Enterprise policies restrict which GitHub Actions can be used.

Solution: An admin must add github/gh-aw@* to the organization’s allowed actions, either through Settings → Actions → Policies → “Allow select actions and reusable workflows” (docs), or by editing a centralized policies/actions.yml:

allowed_actions:
- "actions/*"
- "github/gh-aw@*"

Wait a few minutes for policy propagation, then re-run.

The CLI validates three permission layers in Repository Settings → Actions → General: enable Actions, switch from local-only restrictions to allowing GitHub-created or all actions, and, if you’re using a selective allowlist, enable GitHub-created actions as well. See the repository Actions settings docs and allowlist details.

If a frontmatter setting appears to be silently ignored, the field name may be misspelled. The compiler does not warn about unknown field names — they are silently discarded.

Common fixes: validate YAML syntax (indentation and key: value spacing), confirm required fields such as on:, and check types against the schema with gh aw compile --verbose.

If no lock file is generated, fix the reported errors (gh aw compile 2>&1 | grep -i error) and confirm .github/workflows/ is writable. If stale .lock.yml files remain after deleting a workflow .md, remove them with gh aw compile --purge.

Import paths are relative to the repository root, for example .github/workflows/shared/tools.md; verify the expected files with git status. A workflow can import only one file from .github/agents/. If compilation hangs, check for circular imports and remove the cycle.

Configure using toolsets: (tools reference):

tools:
github:
toolsets: [repos, issues]

Check GitHub Toolsets, combine toolsets (toolsets: [default, actions]), or inspect with gh aw mcp inspect <workflow>.

Verify package installation, syntax, and environment variables:

mcp-servers:
my-server:
command: "npx"
args: ["@myorg/mcp-server"]
env:
API_KEY: "${{ secrets.MCP_API_KEY }}"

When integrating OpenCode-compatible engines, runs can complete without ever invoking MCP or file tools. Use an explicit opencode.jsonc config. Port 10004 is the local AWF API proxy port (with --enable-api-proxy); MCP_GATEWAY_PORT and MCP_GATEWAY_API_KEY are expanded from workflow env at runtime (substitute concrete values when running outside a workflow):

{
"provider": {
"copilot-proxy": {
"api": "http://host.docker.internal:10004",
"options": {
"apiKey": "awf-copilot-proxy"
},
"models": {
"gpt-4.1": {},
"claude-sonnet-4-6": {}
}
}
},
"model": "copilot-proxy/claude-sonnet-4-6",
"mcp": {
"safeoutputs": {
"type": "http",
"url": "http://host.docker.internal:${MCP_GATEWAY_PORT}/mcp/safeoutputs",
"headers": { "Authorization": "${MCP_GATEWAY_API_KEY}" },
"disabled": false,
"timeout": 30000
}
},
"agent": {
"build": {
"permission": {
"bash": "allow", "edit": "allow", "read": "allow",
"glob": "allow", "grep": "allow", "write": "allow",
"external_directory": "allow"
}
}
}
}

OpenCode does not auto-discover MCP servers, so declare an explicit top-level mcp block with routed URLs such as http://host.docker.internal:${MCP_GATEWAY_PORT}/mcp/<server-name>. Use agent.build.permission (singular), not permissions, and set external_directory: allow only when you truly need access outside the workspace because the default ask behaves like a deny in non-interactive runs.

For direct Copilot endpoints (api.githubcopilot.com), do not append /v1. For other OpenAI-compatible providers, use the provider’s documented base path so /chat/completions is appended correctly. Keep the local proxy URL (http://host.docker.internal:10004) unchanged.

When using --enable-api-proxy, pass COPILOT_GITHUB_TOKEN in the execute step’s env: so the proxy can authenticate:

- name: Execute
env:
COPILOT_GITHUB_TOKEN: ${{ steps.copilot-token.outputs.token }}
run: |
awf --enable-api-proxy <workflow-args> -- opencode run "<prompt>"

Add domains to network.allowed:

network:
allowed:
- github.com
- "*.github.io"

Error: Cannot find module 'playwright' — Playwright is provided as MCP tools, not as an npm package. Use the MCP tools instead of require('playwright'):

// ✗ Don't: const playwright = require('playwright')
// ✓ Do: use MCP tools
await mcp__playwright__browser_navigate({ url: "https://example.com" });
await mcp__playwright__browser_snapshot();

See Playwright Tool documentation for all available tools.

Playwright MCP Initialization Failure (EOF Error)

Section titled “Playwright MCP Initialization Failure (EOF Error)”

Failed to register tools error="initialize: EOF" name=playwright — Chromium crashes before tool registration completes due to missing Docker security flags. Upgrade to 0.41.0+ with gh extension upgrade gh-aw.

All writes (issues, comments, PR updates) must go through the safe-outputs system — declare the types your workflow needs in frontmatter:

safe-outputs:
create-issue:
title-prefix: "[bot] "
labels: [automation]
add-comment: # no configuration required; uses defaults
update-issue: # no configuration required; uses defaults

If your operation isn’t in the Safe Outputs reference, it may not be supported yet. See the Safe Outputs Specification for the full list.

Disable staged mode:

safe-outputs:
staged: false
create-issue:
title-prefix: "[bot] "
labels: [automation]

GitHub Projects reserves field names like REPOSITORY. Use alternatives (repo, source_repository, linked_repo):

# ✗ Wrong: repository
# ✓ Correct: repo
safe-outputs:
update-project:
fields:
repo: "myorg/myrepo"

Delete conflicting fields in Projects UI and recreate.

If the Copilot CLI is missing, first verify compilation succeeded because compiled workflows install it automatically. If a model is unavailable, fall back to the default (engine: copilot) or choose one your environment exposes, such as engine: {id: copilot, model: gpt-4}.

Copilot License or Inference Access Issues

Section titled “Copilot License or Inference Access Issues”

If a workflow fails at the Copilot inference step despite a correctly configured COPILOT_GITHUB_TOKEN (authentication or quota errors), the PAT owner may lack a valid Copilot license or inference access. Test locally with the Copilot CLI:

Terminal window
export COPILOT_GITHUB_TOKEN="<your-github-pat>"
copilot -p "write a haiku"

If this fails, contact your organization administrator to enable Copilot for the token owner.

Before running Copilot-based workflows on GHES, verify three things: site admins have enabled GitHub Connect, enterprise Copilot licensing, and outbound HTTPS to api.githubcopilot.com and api.enterprise.githubcopilot.com; enterprise or org admins have assigned a Copilot seat to the COPILOT_GITHUB_TOKEN owner and allowed usage by policy; and the workflow targets the enterprise endpoint:

engine:
id: copilot
api-target: api.enterprise.githubcopilot.com
network:
allowed:
- defaults
- api.enterprise.githubcopilot.com

See Enterprise API Endpoint for GHEC/GHES api-target values.

ErrorCauseFix
Error loading models: 400 Bad RequestEnterprise Copilot not licensed or GitHub Connect not enabledEnable GitHub Connect and enterprise Copilot in site admin settings
403 "unauthorized: not licensed to use Copilot"No Copilot seat for PAT ownerSite admin enables Copilot; org admin assigns a seat to the token owner
403 "Resource not accessible by personal access token"Wrong token type or missing permissionsUse fine-grained PAT with Copilot Requests: Read, or classic PAT with copilot scope — see COPILOT_GITHUB_TOKEN
Could not resolve to a RepositoryGH_HOST not set in custom jobsRecompile (gh aw compile), or set GH_HOST=github.company.com explicitly for local CLI commands
Firewall blocking api.<ghes-host>Domain not in allowed listAdd to network.allowed (see below)
gh aw add-wizard creates PR on github.comNot inside a GHES repo cloneRun from within GHES repo, or use gh aw add + gh pr create

For firewall issues, add the GHES domain to your workflow’s allowed list:

engine:
id: copilot
api-target: api.company.ghe.com
network:
allowed:
- defaults
- company.ghe.com
- api.company.ghe.com

Use only allowed expressions such as github.event.issue.number, github.repository, and steps.sanitized.outputs.text; secrets.* and env.* are disallowed. If steps.sanitized.outputs.text is empty, confirm the workflow runs on issue, PR, or comment events rather than push:.

If the docs build fails, do a clean install (cd docs && rm -rf node_modules package-lock.json && npm install && npm run build) and check for malformed frontmatter, MDX syntax errors, or broken links. If tests fail after changes, run make fmt && make lint && make test-unit before iterating.

Add ecosystem identifiers (Network Configuration Guide):

network:
allowed:
- defaults # Infrastructure
- python # PyPI
- node # npm
- containers # Docker
- go # Go modules

If URLs appear as (redacted), add the relevant domains to the allowed list (Network Permissions), for example allowed: [defaults, "api.example.com"]. If remote imports fail to download, verify both network access (curl -I https://raw.githubusercontent.com/github/gh-aw/main/README.md) and authentication (gh auth status). For MCP server timeouts, prefer local servers such as command: "node" with args: ["./server.js"].

If a cache is not restoring, make sure the key pattern matches; caches expire after 7 days, for example cache: { key: deps-${{ hashFiles('package-lock.json') }}, restore-keys: deps- }. If cache memory is not persisting, configure the cache-memory MCP server with a key such as tools.cache-memory.key: memory-${{ github.workflow }}-${{ github.run_id }}.

Integrity Filtering Blocking Expected Content

Section titled “Integrity Filtering Blocking Expected Content”

On public repositories, min-integrity: approved is applied automatically — restricting agent visibility to content from owners, members, and collaborators. As a result, workflows can’t see issues, PRs, or comments from external contributors, and triage workflows don’t process community contributions.

To allow all contributors (only safe when the workflow validates input and uses restrictive safe outputs):

tools:
github:
min-integrity: none

Use min-integrity: unapproved as a middle ground for community triage workflows. See Integrity Filtering for details.

GitHub Actions marks the run as timed_out when the job exceeds timeout-minutes (default: 20 min). The table below maps each engine’s error patterns to the right fix; after updating frontmatter, recompile with gh aw compile. See Long Build Times for caching strategies and self-hosted runner recommendations.

EngineError PatternFix Setting
AllThe job has exceeded the maximum execution time of N minutestimeout-minutes: N in frontmatter
ClaudeBash tool timed out after 60 secondstools: timeout: N (default: 60s)
ClaudeReached maximum number of turns (N). Stopping.max-turns: N
CodexTool call timed out after 120 secondstools: timeout: N (default: 120s)
Copilot(task incomplete, workflow succeeds)max-continuations: N
AnyFailed to register tools error="initialize: timeout"tools: startup-timeout: N
timeout-minutes: 60 # job-level limit
tools:
timeout: 600 # per-tool-call limit (seconds)
startup-timeout: 300 # MCP server startup limit (seconds)
max-turns: 30 # Claude: max turns
max-continuations: 5 # Copilot: autopilot continuations

Common causes include missing tokens, permission mismatches, network restrictions, disabled tools, and rate limits. The quickest path is usually to give an agent the run URL so it can inspect logs and suggest a fix.

Using Copilot Chat (requires agentic authoring setup):

agentic-workflows debug https://github.com/OWNER/REPO/actions/runs/RUN_ID

Using any coding agent (no setup required):

Debug this workflow run using https://raw.githubusercontent.com/github/gh-aw/main/debug.md
The failed workflow run is at https://github.com/OWNER/REPO/actions/runs/RUN_ID

For manual investigation, use gh aw audit <run-id> and gh aw logs, then inspect the generated .lock.yml. See the Debugging Workflows guide for a full walkthrough.

Enable verbose mode (--verbose), set ACTIONS_STEP_DEBUG = true, or inspect MCP config (gh aw mcp inspect). The DEBUG environment variable activates detailed internal logging for any gh aw command — output goes to stderr and each line shows the namespace (workflow:compiler), message, and time since the previous entry. Common namespaces: cli:compile_command, workflow:compiler, workflow:expression_extraction, parser:frontmatter. Wildcards match any suffix.

Terminal window
DEBUG=* gh aw compile # all logs
DEBUG=workflow:* gh aw compile my-workflow # specific package
DEBUG=workflow:*,cli:* gh aw compile my-workflow # multiple packages
DEBUG=*,-workflow:test gh aw compile my-workflow # exclude a logger
DEBUG_COLORS=0 DEBUG=* gh aw compile 2>&1 | tee debug.log # capture to file

For a step-by-step diagnostic checklist, see the Workflow Health Monitoring Runbook.

Start with the reference docs, Error Reference, and Frontmatter Reference. If that doesn’t resolve the issue, search existing issues or open a new one.