GitHub Actions Fix, Crash & Optimization Guide
GitHub Actions CI/CD troubleshooting for failed workflows, caching, and self-hosted runners, plus speed and cost optimization tips.
GitHub Actions Fix, Crash & Optimization Guide
GitHub Actions is GitHub's integrated CI/CD service that runs workflows defined in YAML inside .github/workflows/. Teams use it to build, test, and deploy code automatically on push, pull request, and schedule.
Install / First Setup
- No agent to install: workflows run on GitHub-hosted runners or your own. You only add YAML files under
.github/workflows/in the repo. - Validate locally: use the
acttool (brew install act) to run workflows locally with Docker before pushing. - Secrets: configure under repo Settings → Secrets and variables → Actions; reference them as
${{ secrets.NAME }}in YAML. - Verify: push a minimal workflow and watch it run under the Actions tab.
Common Issues & Fixes
Workflow not triggering / not showing up
Cause: YAML syntax error, wrong on: event, or the file outside .github/workflows/.
Fix: confirm the file is valid YAML and lives in .github/workflows/. Check the on: key (e.g. on: [push, pull_request]). A workflow whose pull_request trigger conflicts with branch protections or fork permissions won't run for forks by default.
Step fails with "command not found" / wrong tool version
Cause: the runner image lacks the tool, or the wrong version is default.
Fix: use actions/setup-node, actions/setup-python, actions/setup-java, etc. to pin versions; or install via package manager in a step. Prefer explicit version pins over the image default.
Permission denied / "Resource not accessible by integration"
Cause: the GITHUB_TOKEN lacks the scope for the action (e.g. writing packages, PRs).
Fix: add a permissions: block to the job or workflow (e.g. permissions: { contents: write, packages: write }). Note the default token has no id-token/write to some scopes unless granted.
Cache not working / always misses
Cause: wrong cache key, or the path doesn't match the tool's cache dir.
Fix: use the dedicated actions/cache with a stable key (include OS and lockfile hash), or the built-in cache: input of setup actions (e.g. setup-node with cache: npm). A changed key forces a miss — that's expected after dependency changes.
Self-hosted runner offline / jobs queued forever
Cause: the runner process stopped, or labels don't match the job's runs-on.
Fix: restart the runner service (sudo systemctl restart actions.runner.* on Linux, or re-run run.sh). Ensure the job's runs-on labels match a registered runner. Check the runner's outward network access to GitHub.
Performance & Optimization
- Caching: cache dependencies (node_modules,
~/.m2,~/.cache/pip,~/go/pkg/mod) withactions/cache; combine with setup actions' nativecache:for best hits. - Low-End / small repos: GitHub-hosted
ubuntu-latestwith dependency caching is enough; keep jobs single and fast. - Mid / team: split lint, test, and build into parallel jobs; use a build matrix only where it speeds coverage. Cache Docker layers with
actions/cache+buildxor a registry. - Workstation / heavy CI: use larger GitHub-hosted runners or self-hosted runners with more CPU/RAM; enable
concurrency:groups to cancel redundant runs on the same branch; runactlocally to fail fast before pushing. - Cost: avoid running full suites on every doc-only change with
paths:filters; settimeout-minutesso stuck jobs don't bill indefinitely.
Version & Compatibility Notes
- Workflows run on runner images that are updated regularly (e.g.
ubuntu-latesttracks a current Ubuntu LTS). Pre-installed tool versions change over time — pin versions explicitly for reproducibility. Consult official release notes for runner image contents. - The
actions/official actions and the YAML schema evolve; deprecated actions are flagged in the Actions tab. Verify current versions before upgrading. - Self-hosted runner OS and the
runs-onlabel semantics are environment-specific — consult official docs for your setup.
FAQ
Q: Where do I put my workflow YAML files?
A: In the .github/workflows/ directory at the repository root. Each .yml/.yaml file there is treated as a workflow. A file with invalid YAML won't appear as a workflow.
Q: Why didn't my workflow run on a fork's pull request? A: By default, workflows from fork pull requests run with a read-only token and no secrets for security. Maintainers must enable "Run workflows from fork pull requests" or run them after merge, depending on repo settings.
Q: How do I make dependency installs faster?
A: Cache them with actions/cache keyed on your lockfile hash, or use the cache: option of actions/setup-*. This avoids re-downloading on every run.
Q: What's the difference between GitHub-hosted and self-hosted runners?
A: GitHub-hosted runners are managed VMs (ephemeral, metered) you select by runs-on: ubuntu-latest etc. Self-hosted runners are machines you register yourself, useful for custom hardware, private networks, or cost at scale.
Q: How do I stop a workflow that's stuck billing me?
A: Cancel the run from the Actions tab, set timeout-minutes on jobs, and use concurrency to auto-cancel superseded runs on the same branch.
Q: How can I test a workflow before pushing?
A: Use the act CLI to run workflows locally with Docker, which approximates the GitHub-hosted environment and surfaces YAML/logic errors quickly.
Related Guides
Accuracy Note
Commands and paths reflect common, real-world setups as of 2026-08. Always verify against your installed version and OS. When in doubt, consult the official GitHub Actions documentation.
Calculator Recommended Adjustment Params
Run the Build Time Calculator with the values referenced in this guide to validate your rig before and after the fix.