# Latchkey Learn - full page index > One line per page: [title](url): description. ## GitHub Actions runners compared - [GitHub Actions runners compared](https://latchkey.dev/learn/runners): Neutral comparisons of GitHub Actions runner vendors, alternatives to GitHub-hosted and self-hosted runners, and migration guides. Prices are read from each vendor's public page on a stated date. - [Latchkey vs Blacksmith for GitHub Actions runners](https://latchkey.dev/learn/runners/latchkey-vs-blacksmith): Latchkey vs Blacksmith on price, cache, runner sizes and free minutes, read from both pricing pages, with the arm64 gap stated plainly. - [Latchkey vs WarpBuild for GitHub Actions runners](https://latchkey.dev/learn/runners/latchkey-vs-warpbuild): Latchkey vs WarpBuild on managed rates, the bring-your-own-cloud mode that undercuts both, separate cache metering, and where each one wins. - [Latchkey vs Buildkite for CI on GitHub](https://latchkey.dev/learn/runners/latchkey-vs-buildkite): Latchkey vs Buildkite is a label change against a platform migration. Seat fees, per vCPU-minute billing and what you give up either way. - [Latchkey vs StarSling for AI on GitHub Actions](https://latchkey.dev/learn/runners/latchkey-vs-starsling): Latchkey vs StarSling: both put AI on your CI, at opposite ends of the failure. One fixes the running job, the other opens a pull request. - [Latchkey vs BuildJet after the BuildJet shutdown](https://latchkey.dev/learn/runners/latchkey-vs-buildjet): Latchkey vs BuildJet is now a migration: BuildJet stopped running GitHub Actions jobs on 31 March 2026. The label map and what it all costs now. - [Latchkey vs GitHub hosted runners, and where each one wins](https://latchkey.dev/learn/runners/latchkey-vs-github-hosted-runners): Latchkey vs GitHub hosted runners for GitHub Actions: the break-even is near 7,700 Linux minutes a month, and GitHub still wins four ways. - [Latchkey vs self-hosted runners, with the ops bill counted](https://latchkey.dev/learn/runners/latchkey-vs-self-hosted-runners): Latchkey vs self-hosted runners for GitHub Actions: a worked monthly cost for an ARC fleet, the utilization break-even, and when self-hosting wins. - [Blacksmith vs Depot for GitHub Actions runners](https://latchkey.dev/learn/runners/blacksmith-vs-depot): Blacksmith vs Depot for GitHub Actions runners: per-minute rates, free minutes, cache limits and billing, read today, with a worked bill. - [Blacksmith vs GitHub Actions hosted runners](https://latchkey.dev/learn/runners/blacksmith-vs-github-hosted-runners): Blacksmith vs GitHub Actions hosted runners on price, hardware, cache and free minutes, read today, with the one workload where Blacksmith costs more. - [Buildkite vs Blacksmith for CI on GitHub](https://latchkey.dev/learn/runners/blacksmith-vs-buildkite): Buildkite vs Blacksmith for GitHub Actions teams: one is a label change, the other a platform move with seat fees. Rates and a 20-person bill. - [Depot vs Blacksmith Docker cache for GitHub Actions builds](https://latchkey.dev/learn/runners/depot-vs-blacksmith-for-docker-builds): Depot vs Blacksmith docker cache in GitHub Actions: a remote BuildKit builder against a sticky disk, with both rate cards and both cache bills. - [Depot vs GitHub Actions hosted runners](https://latchkey.dev/learn/runners/depot-vs-github-hosted-runners): Depot vs GitHub Actions hosted runners: identical published rates, very different machines. What the same $0.006 a minute actually buys. - [Depot vs Namespace for GitHub Actions runners](https://latchkey.dev/learn/runners/depot-vs-namespace): Depot vs Namespace for GitHub Actions: a per-minute rate card against unit minutes, converted to the same money, with both cache bills shown. - [Depot vs WarpBuild for GitHub Actions runners](https://latchkey.dev/learn/runners/depot-vs-warpbuild): Depot vs WarpBuild for GitHub Actions runners: the rates stopped matching. Per-minute prices by size, BYOC at $0.002, and a worked monthly bill. - [Namespace vs Blacksmith for GitHub Actions runners](https://latchkey.dev/learn/runners/namespace-vs-blacksmith): Namespace vs Blacksmith on GitHub Actions runners: the rate looks lower until you match the RAM. Prices, shapes, cache volumes and billing read today. - [Namespace vs GitHub hosted runners, and the unit minute](https://latchkey.dev/learn/runners/namespace-vs-github-hosted-runners): Namespace vs GitHub hosted runners for GitHub Actions: unit minutes converted to rates, the shapes that match, concurrency in vCPU, a worked bill. - [RunsOn vs Blacksmith for GitHub Actions runners](https://latchkey.dev/learn/runners/runs-on-vs-blacksmith): RunsOn vs Blacksmith for GitHub Actions: a flat annual license in your own AWS account against a managed per-minute fleet, with a worked monthly bill. - [RunsOn vs Depot for GitHub Actions runners](https://latchkey.dev/learn/runners/runs-on-vs-depot): RunsOn vs Depot for GitHub Actions: a flat annual license priced by job count against a per-minute meter, with the crossover worked out. - [RunsOn vs GitHub hosted runners, and the three bill lines](https://latchkey.dev/learn/runners/runs-on-vs-github-hosted-runners): RunsOn vs GitHub hosted runners: one metered invoice against a license plus your own AWS bill, with the lines the published comparison leaves out. - [Ubicloud GitHub Actions runners, and where 4 to 7x lands](https://latchkey.dev/learn/runners/ubicloud-vs-github-hosted-runners): Ubicloud GitHub Actions runners publish a 4 to 7x saving. The rate cards give the 4 end; the 7 end carries a speed claim you have to measure. - [Ubicloud vs Blacksmith for GitHub Actions runners](https://latchkey.dev/learn/runners/ubicloud-vs-blacksmith): Ubicloud vs Blacksmith for GitHub Actions: two published rate cards, the premium tier that is on by default, and what each free cache holds. - [WarpBuild vs Blacksmith for GitHub Actions runners](https://latchkey.dev/learn/runners/warpbuild-vs-blacksmith): WarpBuild vs Blacksmith for GitHub Actions: identical x64 rates at every size, so free minutes, arm64, BYOC and concurrency decide it. Read today. - [WarpBuild vs GitHub hosted runners, and its three meters](https://latchkey.dev/learn/runners/warpbuild-vs-github-hosted-runners): WarpBuild vs GitHub hosted runners: managed, bring-your-own-cloud and Docker builders priced separately, against one bundled metered bill. - [WarpBuild vs Namespace for GitHub Actions runners](https://latchkey.dev/learn/runners/warpbuild-vs-namespace): WarpBuild vs Namespace for GitHub Actions: identical Linux rates, opposite cache meters, and a macOS minute that decides most bills. - [Actuated alternatives, and where a flat rate stops paying](https://latchkey.dev/learn/runners/actuated-alternatives): Actuated alternatives compared on the axis that decides it: a flat licence on your own metal against a metered minute, with the crossover worked. - [Blacksmith alternatives for GitHub Actions, priced and ranked](https://latchkey.dev/learn/runners/blacksmith-alternatives): Blacksmith alternatives GitHub Actions teams shortlist, ranked by the rate each vendor published on 2026-09-20, with what each one gives up. - [BuildJet alternatives for GitHub Actions, after the shutdown](https://latchkey.dev/learn/runners/buildjet-alternatives): BuildJet alternative options for GitHub Actions now that BuildJet stopped running jobs on 31 March 2026, with every replacement rate read 2026-09-20. - [Cirrus CI alternative for macOS: where those jobs go](https://latchkey.dev/learn/runners/cirrus-ci-alternatives-for-macos): A Cirrus CI alternative for the macOS half of your pipeline, with every published GitHub Actions macOS shape and rate read on 2026-09-20. - [Depot alternatives for GitHub Actions, after the price change](https://latchkey.dev/learn/runners/depot-alternatives): Depot alternatives GitHub Actions teams are pricing now that Depot lists $0.006 a minute, level with GitHub-hosted. Every rate read 2026-09-20. - [Fastest GitHub Actions runners: what is actually published](https://latchkey.dev/learn/runners/fastest-github-actions-runners): The fastest GitHub Actions runners, judged only on published hardware and published benchmarks, with who ran each number and when it was read. - [GitHub Actions runner alternatives, ranked by published rate](https://latchkey.dev/learn/runners/github-actions-runner-alternatives): GitHub Actions runner alternatives ranked by the rate each vendor published on 2026-09-20, with the memory it buys and what each one does not do. - [Managed GitHub Actions runners compared, by how you pay](https://latchkey.dev/learn/runners/managed-github-actions-runners-compared): Managed GitHub Actions runners compared on where jobs run, what you still operate and which meters sit beside the headline rate. Every price dated. - [Namespace runners alternatives, and what the unit minute hides](https://latchkey.dev/learn/runners/namespace-alternatives): Namespace runners alternatives for GitHub Actions, priced against its unit-minute model with every rate read on 2026-09-20 and what each one gives up. - [RunsOn alternatives: keep the AWS account, or hand it over](https://latchkey.dev/learn/runners/runs-on-alternatives): RunsOn alternatives split on one question: does the compute stay in your AWS account? Licence, bring-your-own-cloud and metered options, each dated. - [WarpBuild alternatives, for the managed price and the BYOC one](https://latchkey.dev/learn/runners/warpbuild-alternatives): WarpBuild alternatives for GitHub Actions, priced separately against its managed rate and its flat bring-your-own-cloud rate, read on 2026-09-20. - [A CodeBuild GitHub Actions runner alternative, and the cutover](https://latchkey.dev/learn/runners/migrate-from-aws-codebuild-runners): A CodeBuild GitHub Actions runner alternative means undoing a project, a webhook and a composite label: the label map, the buildspec trap, billing. - [Actions Runner Controller alternative: moving ARC off Kubernetes](https://latchkey.dev/learn/runners/migrate-from-actions-runner-controller): An Actions Runner Controller alternative for GitHub Actions: what carries over from ARC, the runs-on change, and the operations cost worked out. - [Cirrus CI shutting down: moving the macOS jobs first](https://latchkey.dev/learn/runners/migrate-from-cirrus-ci): Cirrus CI shutting down on 1 June 2026 leaves every .cirrus.yml task homeless. The GitHub Actions migration, with macOS rates read 2026-09-20. - [Migrate from Blacksmith: the label map and what breaks](https://latchkey.dev/learn/runners/migrate-from-blacksmith): Migrate from Blacksmith to another GitHub Actions runner: the label map by size, what replaces sticky disks and the Docker cache, and when to stay. - [Migrate from BuildJet, now that the runners are gone](https://latchkey.dev/learn/runners/migrate-from-buildjet): Migrate from BuildJet to another GitHub Actions runner: the pre-flight checklist, the runs-on diff, and what changes when the cache allowance halves. - [Migrate from Depot runners without losing the cache](https://latchkey.dev/learn/runners/migrate-from-depot): Migrate from Depot runners to another GitHub Actions runner: the label map, what the branch-shared cache does next, and the job length where it pays. - [Migrate from Namespace runners without a cold cache](https://latchkey.dev/learn/runners/migrate-from-namespace): Migrate from Namespace runners: the profile label map, the nscloud actions to undo, and the cache scope change that makes every new branch start cold. - [Migrate from self-hosted GitHub Actions runners without a rewrite](https://latchkey.dev/learn/runners/migrate-from-self-hosted-runners): Migrate from self-hosted GitHub Actions runners without a rewrite: the checklist, the runs-on diff, and the steps that only worked on your own box. - [Migrate from WarpBuild, and what the snapshot was doing](https://latchkey.dev/learn/runners/migrate-from-warpbuild): Migrate from WarpBuild to another GitHub Actions runner: the label map, the metered add-ons that leave the bill with their features, and BYOC mode. - [ARC vs managed runners for GitHub Actions](https://latchkey.dev/learn/runners/actions-runner-controller-vs-managed-runners): ARC vs managed runners: what Helm actually installs, the list GitHub Support will not help with, and the one line each option changes in a job. - [Are GitHub larger runners worth it, or is a managed runner cheaper?](https://latchkey.dev/learn/runners/github-larger-runners-vs-managed-runners): Are github larger runners worth it? Rates and sizes against managed GitHub Actions runners, the included-minute rule, and a worked month at 4 vCPU. - [GitHub Actions vs Argo Workflows: which one runs what](https://latchkey.dev/learn/runners/github-actions-vs-argo-workflows): GitHub Actions vs Argo Workflows: the fan-out ceiling in each, what a step costs in pods, and why most teams that compare them end up running both. - [GitHub Actions vs Azure Pipelines: two Microsoft billing models](https://latchkey.dev/learn/runners/github-actions-vs-azure-pipelines): GitHub Actions vs Azure Pipelines: one sells minutes and caps concurrency, the other sells the concurrency. What a month of each actually costs. - [GitHub Actions vs Concourse CI: pushed at, or polling](https://latchkey.dev/learn/runners/github-actions-vs-concourse): GitHub Actions vs Concourse: one reacts to a webhook, the other polls resources every minute. What that costs you in branches and in nodes to run. - [GitHub Actions vs Drone CI, and where Drone went](https://latchkey.dev/learn/runners/github-actions-vs-drone-ci): GitHub Actions vs Drone CI: the repository redirects to Harness, the license caps commercial use at 32 days, and the branch stopped moving in April. - [GitHub Actions vs GitLab CI: what a minute costs on each](https://latchkey.dev/learn/runners/github-actions-vs-gitlab-ci-compared): GitHub Actions vs GitLab CI, priced properly: GitLab multiplies each minute by a cost factor, GitHub sells a flat rate per size. They cross at 20,500. - [GitHub Actions vs Jenkins: counting what you would maintain](https://latchkey.dev/learn/runners/github-actions-vs-jenkins-compared): GitHub Actions vs Jenkins with the catalog counted: 2,111 plugins in the update center, 767 with a published security warning, 267 marked deprecated. - [GitHub Actions vs Woodpecker CI: the smallest honest self-host](https://latchkey.dev/learn/runners/github-actions-vs-woodpecker): GitHub Actions vs Woodpecker CI: a server and agent that idle at 100 MB and 30 MB, six supported forges, and the Drone license change that created it. - [GitHub-hosted vs self-hosted vs managed runners](https://latchkey.dev/learn/runners/github-hosted-vs-self-hosted-vs-managed-runners): GitHub-hosted vs self-hosted vs managed GitHub Actions runners on price, hardware, cache, concurrency and ops, with rates read today. - [Self-hosted vs managed runners for GitHub Actions](https://latchkey.dev/learn/runners/self-hosted-vs-managed-runners): Self-hosted vs managed runners for GitHub Actions: the ops work GitHub documents, isolation semantics, and a month priced at four utilizations. - [Blacksmith CI pricing, explained](https://latchkey.dev/learn/runners/blacksmith-pricing-explained): Blacksmith CI pricing for GitHub Actions runners, read today: every rate by platform and size, the free minutes, the add-ons, and what is unpublished. - [Blacksmith runner not picked up, and the other errors teams hit](https://latchkey.dev/learn/runners/blacksmith-troubleshooting): Blacksmith runner not picked up is usually a label typo or a missing GitHub App. Eight failures on Blacksmith GitHub Actions runners, with the fixes. - [RunsOn GitHub Actions runners explained](https://latchkey.dev/learn/runners/runs-on-explained): RunsOn GitHub Actions runners are EC2 instances in your own AWS account behind a flat licence: what it installs, the label syntax, and the two bills. - [What Depot GitHub Actions runners are, and how they work](https://latchkey.dev/learn/runners/depot-runners-explained): How Depot GitHub Actions runners work: ephemeral EC2 by size, per-second tracking with a size multiplier, the shared cache, and the plan minutes. - [What is Blacksmith CI, and how do its runners work?](https://latchkey.dev/learn/runners/blacksmith-runners-explained): What Blacksmith CI is, how its GitHub Actions runners work, every published size and label, the caching model, and the limits its own docs record. - [What is Ubicloud CI, and what does it actually cost?](https://latchkey.dev/learn/runners/ubicloud-runners-explained): What is Ubicloud CI: an open source cloud selling GitHub Actions runners from Germany. Every published rate, the real multiple, and the limits. - [What Namespace runners are, and how unit minutes work](https://latchkey.dev/learn/runners/namespace-runners-explained): How namespace runners work on GitHub Actions: profiles and labels, machine shapes, unit-minute billing, cache volumes, and the published ceilings. - [What WarpBuild GitHub Actions runners are, and how they work](https://latchkey.dev/learn/runners/warpbuild-runners-explained): How WarpBuild GitHub Actions runners work: the runner tags and rates, a cache that needs its own action, separate Docker builders, and BYOC at $0.002. ## GitHub Actions cost - [GitHub Actions cost](https://latchkey.dev/learn/cost): How GitHub Actions billing works, what macOS, Windows, larger and arm64 runners cost, and the changes that actually reduce the bill. - [GitHub Actions cache storage cost per GB, and artifacts](https://latchkey.dev/learn/cost/github-actions-cache-and-artifact-storage-cost): GitHub Actions cache storage cost per GB is $0.07 and artifacts are $0.25, but only one of them usually bills. The allowances, accrual and retention. - [GitHub Actions cost calculator](https://latchkey.dev/learn/cost/github-actions-cost-calculator): Use this GitHub Actions cost calculator to price your Linux, Windows and macOS minutes at published rates and see the same month on Latchkey runners. - [GitHub Actions minutes and billing, explained](https://latchkey.dev/learn/cost/github-actions-minutes-and-billing-explained): GitHub Actions minutes are metered per job and rounded up. What the clock counts, which SKU each runner label bills as, and where the bill appears. - [GitHub Actions pricing changes in 2026](https://latchkey.dev/learn/cost/github-actions-pricing-changes-2026): GitHub Actions pricing changes 2026, dated to the changelog entry behind each one, including the self-hosted charge announced and then postponed. - [How GitHub Actions pricing works](https://latchkey.dev/learn/cost/github-actions-pricing-explained): How GitHub Actions pricing works: included minutes, per-minute rates, larger runners and storage, with every rate read from GitHub in September 2026. - [Is GitHub Actions free?](https://latchkey.dev/learn/cost/is-github-actions-free): Are GitHub Actions free? Yes on public repositories with standard runners, partly on private ones, never on larger runners, with the arithmetic. - [GitHub Actions arm64 runners pricing, size by size](https://latchkey.dev/learn/cost/github-actions-arm64-runners-pricing): GitHub Actions arm64 runners pricing against x64 at every size, with the discount at each step and how much slower arm64 may run before it pays. - [GitHub Actions larger runners pricing](https://latchkey.dev/learn/cost/github-actions-larger-runners-pricing): GitHub Actions larger runners pricing by size, with the vCPU, RAM and disk behind each rate, the two exceptions, and what to size up for. - [GitHub Actions macOS runner cost](https://latchkey.dev/learn/cost/github-actions-macos-runner-cost): GitHub Actions macOS runner cost is $0.062 a minute against $0.006 on Linux: worked iOS examples, larger macOS rates, and what to move off macOS. - [GitHub Actions runner cost by size](https://latchkey.dev/learn/cost/github-actions-runner-cost-by-size): A GitHub Actions runner cost comparison that prices a job, not a minute: the speedup each size must buy, and one job on three published rate cards. - [GitHub Actions Windows runner cost per minute](https://latchkey.dev/learn/cost/github-actions-windows-runner-cost): GitHub Actions Windows runner cost per minute is $0.010 against $0.006 on Linux: every size, what the allowance buys, and which jobs need Windows. - [What a self-hosted GitHub runner really costs](https://latchkey.dev/learn/cost/self-hosted-github-runner-total-cost): Self-hosted GitHub runner cost is zero on your GitHub Actions bill and not zero for you: the break-even against hosted rates, and the postponed fee. - [GitHub Actions ran out of minutes](https://latchkey.dev/learn/cost/github-actions-out-of-minutes): GitHub Actions ran out of minutes? What stops, what keeps running, how to see where the allowance went, and four ways to stop hitting the wall. - [How to reduce GitHub Actions costs](https://latchkey.dev/learn/cost/reduce-github-actions-costs): Seven changes that reduce GitHub Actions cost, ranked by what each one saves on the same worked month, with the before and after YAML for every one. - [Identify high cost GitHub Actions workflows](https://latchkey.dev/learn/cost/measure-github-actions-costs): Identify high cost GitHub Actions workflows with the timing API and the usage report, then rank them by money rather than by minutes before you edit. - [Why is my CI so expensive? A diagnostic](https://latchkey.dev/learn/cost/why-is-my-ci-so-expensive): Why is my CI so expensive: six shapes of GitHub Actions invoice, what each one usually means, and the single check that confirms or clears each cause. ## Runner failures Latchkey repairs - [Runner failures Latchkey repairs](https://latchkey.dev/learn/failures): The failures that are about the runner and the network, not your code. Each page reproduces the failure on a Latchkey runner and shows what the runner does about it. - [Exit code 143 in GitHub Actions](https://latchkey.dev/learn/failures/exit-code-143-sigterm-in-ci): Exit code 143 in GitHub Actions means SIGTERM reached your step, not a crash. Tell cancellation, a step timeout and a reclaimed machine apart. - [GitHub Actions exit code 137: the step was killed, not crashed](https://latchkey.dev/learn/failures/exit-code-137-in-github-actions): Exit code 137 in GitHub Actions is SIGKILL, almost always the out-of-memory killer. Confirm the cause, lower the peak, and size the runner. - [JavaScript heap out of memory in GitHub Actions](https://latchkey.dev/learn/failures/javascript-heap-out-of-memory-in-ci): Fix "JavaScript heap out of memory" in GitHub Actions: raise the V8 old-space ceiling through NODE_OPTIONS, and size the runner to back it. - [OutOfMemoryError: Java heap space in GitHub Actions](https://latchkey.dev/learn/failures/java-heap-space-out-of-memory-in-ci): Fix "OutOfMemoryError: Java heap space" in GitHub Actions by raising the heap of the JVM that actually failed, not the one your workflow configures. - [Python MemoryError in GitHub Actions](https://latchkey.dev/learn/failures/python-memoryerror-in-ci): Python MemoryError in GitHub Actions is the interpreter refusing one allocation, not the kernel OOM killer. Tell the two apart and cut the peak. - [How to free disk space on GitHub Actions runners](https://latchkey.dev/learn/failures/free-disk-space-on-github-actions-runners): Free disk space on a GitHub Actions runner in the order that pays: what to remove, what each directory gives back, and when to stop bothering. - [No space left on device in GitHub Actions](https://latchkey.dev/learn/failures/no-space-left-on-device-github-actions): Fix "No space left on device" in GitHub Actions: find what filled the 14 GB, reclaim it before the heavy step, and know when it is inodes. - [Command not found exit code 127 in GitHub Actions](https://latchkey.dev/learn/failures/command-not-found-exit-127-in-ci): A command not found exit code 127 step in GitHub Actions means bash searched PATH and found nothing. Install the tool, or put its directory on PATH. - [Error while loading shared libraries in CI](https://latchkey.dev/learn/failures/error-while-loading-shared-libraries-in-ci): Fix "error while loading shared libraries" in CI: read the soname, install the package that ships it, and know when the loader path is the problem. - [A Docker registry mirror for GitHub Actions](https://latchkey.dev/learn/failures/docker-registry-mirror-for-github-actions): Run a Docker pull-through cache for GitHub Actions: what a registry mirror covers, what it does not, and measured pull times with and without one. - [apt Hash Sum mismatch in CI](https://latchkey.dev/learn/failures/apt-hash-sum-mismatch-in-ci): An apt Hash Sum mismatch in GitHub Actions means a mirror served an index its own Release file does not vouch for. Here is the fix that lasts. - [AWS CLI ThrottlingException and Rate exceeded in CI](https://latchkey.dev/learn/failures/aws-cli-throttlingexception-in-ci): Fix ThrottlingException in GitHub Actions: the AWS CLI retry settings that change what it really does, and the calls it should stop making. - [bundler could not fetch specs rubygems ci: which fetcher failed](https://latchkey.dev/learn/failures/bundler-could-not-fetch-specs-in-ci): A bundler could not fetch specs rubygems ci failure names the last of three fetchers, not the first. Read which one spoke, then fix that layer. - [Cache service responded with 503 or 429 in GitHub Actions](https://latchkey.dev/learn/failures/github-actions-cache-service-503-429): Fix cache service responded with 503 and 429 in GitHub Actions: keep a cache blip from failing the build, and tell a real outage from your own load. - [cargo spurious network error is a warning, not the failure](https://latchkey.dev/learn/failures/cargo-spurious-network-error-in-ci): A cargo spurious network error line is a warning that cargo is about to retry. Read the countdown, then read the error that actually ended the build. - [composer could not resolve host ci and the errno that decides](https://latchkey.dev/learn/failures/composer-network-and-dns-errors-in-ci): A composer could not resolve host ci failure carries a curl errno, and that number says whether Composer already retried it. Read it first. - [could not get lock /var/lib/dpkg/lock, and who is holding it](https://latchkey.dev/learn/failures/apt-could-not-get-lock-in-ci): A could not get lock /var/lib/dpkg/lock failure either names a holder or it does not, and that decides the fix. Read the clause, then set the wait. - [Docker Hub pull rate limit in GitHub Actions](https://latchkey.dev/learn/failures/docker-hub-pull-rate-limit-in-ci): Fix the Docker pull rate limit in GitHub Actions: authenticate the pull that fails, count what the job really pulls, and put a cache in front of Hub. - [Docker net/http: TLS handshake timeout in CI](https://latchkey.dev/learn/failures/docker-tls-handshake-timeout-in-ci): A Docker TLS handshake timeout in CI means the pull reached the registry and the handshake never finished. Here is what to change in GitHub Actions. - [EAI_AGAIN and could not resolve host in GitHub Actions](https://latchkey.dev/learn/failures/eai-again-could-not-resolve-host-in-ci): Fix EAI_AGAIN and could not resolve host in GitHub Actions: tell a dead resolver from a wrong name, and give the process that failed one that answers. - [ECONNRESET and connection reset by peer in CI](https://latchkey.dev/learn/failures/connection-reset-by-peer-econnreset-in-ci): ECONNRESET in GitHub Actions is a TCP reset, not a timeout. Read which tool printed it, then fix the transfer rather than the tool that reported it. - [err_pnpm_fetch_503 and the rest of the pnpm fetch codes](https://latchkey.dev/learn/failures/pnpm-fetch-errors-in-ci): err_pnpm_fetch_503 means the registry answered and refused. Read the code, know what pnpm already retried, and set the settings that exist. - [error writing layer blob: failed to reserve cache](https://latchkey.dev/learn/failures/buildx-failed-to-reserve-cache-gha): Fix error writing layer blob failed to reserve cache in GitHub Actions: why the buildx gha cache export is refused, and which jobs should export it. - [gcloud resource_exhausted quota ci: rate quota or allocation](https://latchkey.dev/learn/failures/gcloud-quota-exceeded-in-ci): A gcloud resource_exhausted quota ci failure is one of several shapes Google gives one condition. Tell a rate quota from an allocation quota first. - [ghcr toomanyrequests, and why anonymous still means a token](https://latchkey.dev/learn/failures/ghcr-rate-limit-in-ci): A ghcr toomanyrequests response is a registry error code with a 429 behind it. See what GitHub really publishes, then authenticate the pull. - [GitHub API rate limit exceeded in Actions](https://latchkey.dev/learn/failures/github-api-rate-limit-exceeded-in-ci): GitHub API rate limit exceeded in Actions means the token your workflow step used has spent its hour. Which budget you are on, and how to stay in it. - [go proxy.golang.org timeout ci and what the message proves](https://latchkey.dev/learn/failures/go-module-proxy-timeout-in-ci): A go proxy.golang.org timeout ci failure names one request. Tell a dial timeout from a 5xx, then fix the separator that made it fatal. - [helm another operation is in progress is a status, not a lock](https://latchkey.dev/learn/failures/helm-another-operation-in-progress-in-ci): A helm another operation is in progress failure reads a stored status field, not a live lock. Nothing times out, so learn which record to change. - [kubectl unable to connect to the server ci, or refused, or neither](https://latchkey.dev/learn/failures/kubectl-unable-to-connect-to-the-server-in-ci): A kubectl unable to connect to the server ci failure picks one of three sentences by branch. The one you get says how far the request actually got. - [maven could not transfer artifact ci, not a missing jar](https://latchkey.dev/learn/failures/maven-could-not-transfer-artifact-in-ci): A maven could not transfer artifact ci failure is a transport error, not a missing jar. Tell the two apart, then set the retry property that is read. - [npm ERR! network errors in GitHub Actions](https://latchkey.dev/learn/failures/npm-network-errors-in-ci): Fix npm ERR! network in GitHub Actions by reading the code under it: which registry failures are worth a retry, and which will never pass. - [nu1301 unable to load service index, and which source failed](https://latchkey.dev/learn/failures/nuget-nu1301-service-index-unreachable-in-ci): A nu1301 unable to load service index error means restore never read a feed. Find which source failed, then fix the retry and the source list. - [pip ReadTimeoutError and 429 from PyPI in CI](https://latchkey.dev/learn/failures/pip-read-timeout-and-429-in-ci): Fix pip ReadTimeoutError and 429 responses from PyPI in GitHub Actions: raise the timeout the failing pip reads, and cache the wheels it downloads. - [playwright chromium download failed ci, five times over](https://latchkey.dev/learn/failures/playwright-browser-download-failed-in-ci): When playwright chromium download failed ci appears, five attempts have run, over three CDN hosts unless you set a download host. Here is the fix. - [poetry install network error ci next to conda HTTP 000](https://latchkey.dev/learn/failures/poetry-and-conda-network-errors-in-ci): A poetry install network error ci failure and a conda HTTP 000 hide the same event. Two tools, two retry policies, two contradictory verdicts. - [RPC failed with curl 56 in GitHub Actions](https://latchkey.dev/learn/failures/git-rpc-failed-curl-56-in-ci): Fix RPC failed curl 56 in GitHub Actions: the clone died mid-transfer, so fetch less, retry the drop, and skip the buffer setting that does nothing. - [terraform init registry timeout ci: four layers, one message](https://latchkey.dev/learn/failures/terraform-provider-registry-timeout-in-ci): A terraform init registry timeout ci failure stacks four messages into one diagnostic. Read it from the bottom, then change the right timeout. - [The Cypress binary is missing in CI](https://latchkey.dev/learn/failures/cypress-binary-missing-in-ci): The Cypress binary is missing in GitHub Actions when the folder the install wrote to and the folder the test job reads are not the same path. - [uv failed to fetch ci, or the retry line that replaces it](https://latchkey.dev/learn/failures/uv-fetch-failed-in-ci): A uv failed to fetch ci error only appears when uv did not retry. When it did, a different top line replaces it. Read which one you have first. - [yarn network timeout ci: two Yarns, two different fixes](https://latchkey.dev/learn/failures/yarn-network-timeout-in-ci): A yarn network timeout ci failure reads differently in Yarn 1 and Yarn 4. Identify which one you are on, then use the setting that version has. - [Cargo.lock needs to be updated --locked in CI](https://latchkey.dev/learn/failures/cargo-lock-needs-update-in-ci): Cargo.lock needs to be updated --locked in CI means the manifest moved and the lockfile did not. Relock locally, commit both, and keep the flag in CI. - [ERR_PNPM_OUTDATED_LOCKFILE in GitHub Actions](https://latchkey.dev/learn/failures/pnpm-outdated-lockfile-in-ci): Fix ERR_PNPM_OUTDATED_LOCKFILE in GitHub Actions: pnpm freezes the lockfile in CI by default, so regenerate pnpm-lock.yaml and commit it. - [npm ci package-lock out of sync in GitHub Actions](https://latchkey.dev/learn/failures/npm-ci-lockfile-out-of-sync): Fix npm ci package-lock out of sync in GitHub Actions: regenerate package-lock.json, commit it with the manifest, and gate the drift in review. - [Yarn frozen-lockfile needs update](https://latchkey.dev/learn/failures/yarn-frozen-lockfile-needs-update): Fix yarn frozen-lockfile needs update in GitHub Actions: package.json asks for something yarn.lock does not describe. Regenerate it and commit it. - [Fork retry resource temporarily unavailable CI failures](https://latchkey.dev/learn/failures/runner-fork-retry-resource-unavailable): Fork retry resource temporarily unavailable CI failures are a process limit, not memory. Read the errno, count the threads, and cap the parallelism. - [GitHub Actions flaky tests that pass on retry](https://latchkey.dev/learn/failures/flaky-tests-passing-on-retry-in-ci): Get GitHub Actions flaky tests retry right: measure the re-run rate, classify the failure, and retry only the one class where a retry is honest. - [GitHub Actions job timed out](https://latchkey.dev/learn/failures/github-actions-job-timed-out): A GitHub Actions job timed out because one of three clocks fired. Find which one, then fix the hang or the budget rather than raising the wrong limit. - [GitHub Actions runner offline](https://latchkey.dev/learn/failures/self-hosted-runner-offline): Fix a GitHub Actions runner offline: the three states GitHub means by Offline, how to tell them apart, and how to stop the runner dropping out again. - [GitHub Actions startup_failure](https://latchkey.dev/learn/failures/github-actions-startup-failure): A GitHub Actions startup_failure means the run never compiled, so no job and no logs exist. Check the workflow file on the ref that raised the event. - [Job killed no output watchdog errors in CI](https://latchkey.dev/learn/failures/runner-watchdog-killed-no-output): A job killed no output watchdog message comes from Travis or CircleCI. GitHub Actions has no idle timer, so what ends a quiet job there is a clock. - [The hosted runner encountered an error while running your job](https://latchkey.dev/learn/failures/hosted-runner-encountered-an-error): Fix "the hosted runner encountered an error while running your job" in GitHub Actions: tell a platform fault from a job that killed its own runner. - [The runner has received a shutdown signal](https://latchkey.dev/learn/failures/runner-received-a-shutdown-signal): When the runner has received a shutdown signal in GitHub Actions, the agent was stopped mid-job. What causes it on hosted, ARC and spot machines. - [The runner lost communication with the server](https://latchkey.dev/learn/failures/runner-lost-communication-with-the-server): Fix "the runner lost communication with the server" in GitHub Actions: the agent stopped answering, and the cause is usually the host, not the link. - [Waiting for a runner to pick up this job in GitHub Actions](https://latchkey.dev/learn/failures/job-stuck-queued-waiting-for-runner): Fix a GitHub Actions job stuck on "Waiting for a runner to pick up this job": match the labels, check the group, the concurrency ceiling and billing. ## GitHub Actions workflow errors - [GitHub Actions workflow errors](https://latchkey.dev/learn/github-actions): The errors GitHub Actions itself raises: expressions, reusable workflows, permissions and secrets, caching and artifacts, runner labels. - [dorny/paths-filter outputs always false in GitHub Actions](https://latchkey.dev/learn/github-actions/gha-paths-filter-dorny-no-output): Fix dorny/paths-filter outputs always false in GitHub Actions: the diff base it could not resolve, and the string your condition really compares. - [GitHub Actions always() skipped when canceled](https://latchkey.dev/learn/github-actions/github-actions-if-always-skipped-when-canceled): GitHub Actions always() skipped when canceled comes down to when the condition is read. See the cancellation sequence, then guard work that counts. - [GitHub Actions composite action inputs not passed to run steps](https://latchkey.dev/learn/github-actions/github-actions-composite-action-inputs-not-passed): GitHub Actions composite action inputs not passed is usually the environment variable habit. Composite steps get inputs one way and only one way. - [GitHub Actions composite action no such file or directory](https://latchkey.dev/learn/github-actions/gha-action-path-not-resolved-composite): A GitHub Actions composite action no such file error means a run step resolved the path against the caller checkout. Anchor it to github.action_path. - [GitHub Actions composite action unexpected input](https://latchkey.dev/learn/github-actions/gha-composite-action-input-error): GitHub Actions composite action unexpected input is a name comparison against action.yml. Read both errors a composite raises and the shell rule. - [GitHub Actions composite action working-directory, and what reaches it](https://latchkey.dev/learn/github-actions/gha-composite-working-directory-ignored): A GitHub Actions composite action working-directory is joined onto the workspace, and job defaults never reach it. See the branch that decides both. - [GitHub Actions concurrency cancel-in-progress without a group](https://latchkey.dev/learn/github-actions/gha-concurrency-cancel-in-progress-without-group): GitHub Actions concurrency cancel-in-progress cannot stand alone, because the schema marks group required. See what the key does and how to scope it. - [GitHub Actions concurrency job stuck pending is not a deadlock](https://latchkey.dev/learn/github-actions/gha-concurrency-pending-deadlock): A GitHub Actions concurrency job stuck pending is waiting on a group somewhere else in the repository. Find which of four mechanisms is holding it. - [GitHub Actions continue-on-error on a matrix, and the green run](https://latchkey.dev/learn/github-actions/github-actions-continue-on-error-with-matrix-masks-real-failure): GitHub Actions continue-on-error on a matrix applies to every leg, so one experimental combination turns the whole matrix into advisory checks. - [GitHub Actions detached HEAD after actions/checkout](https://latchkey.dev/learn/github-actions/gha-checkout-detached-head-default): GitHub Actions detached HEAD after actions/checkout is documented behavior, not a bug. See which refs detach and name the branch you meant. - [GitHub Actions env var with special characters in a run step](https://latchkey.dev/learn/github-actions/github-actions-env-special-characters-not-escaped): A GitHub Actions env var with special characters breaks a run step because expressions are pasted into the script before any shell reads it. - [GitHub Actions environment variable not expanding in steps](https://latchkey.dev/learn/github-actions/gha-env-var-not-expanding): A GitHub Actions environment variable not expanding in steps has three separate causes, each with its own moment. Find which of the three you have. - [GitHub Actions exceeded max expression length, and what counts](https://latchkey.dev/learn/github-actions/github-actions-expression-too-long-21000-chars): GitHub Actions exceeded max expression length caps one expression at 21000 characters, not your file. See what is counted and how to get under it. - [GitHub Actions fromJSON matrix fails to expand](https://latchkey.dev/learn/github-actions/gha-fromjson-matrix-not-array): A GitHub Actions fromJSON matrix fails when the upstream output is empty or is not an array. Here are the four messages and which branch emits each. - [GitHub Actions fromJSON unable to parse, and what it really says](https://latchkey.dev/learn/github-actions/gha-fromjson-unable-to-parse-in-ci): GitHub Actions fromJSON unable to parse is not the wording the runner uses. See the two messages it does produce and which one you are reading. - [GitHub Actions if condition always runs, and the shape that causes it](https://latchkey.dev/learn/github-actions/github-actions-if-condition-string-always-runs): A GitHub Actions if condition always runs when the value is a string holding an expression. Quoting the whole condition is not what breaks it. - [GitHub Actions if: always() runs a step after cancellation](https://latchkey.dev/learn/github-actions/gha-if-always-vs-success-misuse): GitHub Actions if: always() returns true in every state, cancellation included. Here is what the parser does to the conditions you write. - [GitHub Actions invalid pattern paths filter, and the quoting rule](https://latchkey.dev/learn/github-actions/gha-paths-invalid-pattern): A GitHub Actions invalid pattern paths filter is usually rejected by YAML before any filter sees it. Read the documented quoting rule first. - [GitHub Actions invalid workflow file on this ref](https://latchkey.dev/learn/github-actions/github-actions-skipping-check-workflow-invalid-on-ref): GitHub Actions invalid workflow file on this ref blocks a required check with nothing red. Find the failing ref, then read the startup annotation. - [GitHub Actions invalid workflow reference on a called workflow](https://latchkey.dev/learn/github-actions/github-actions-reusable-workflow-uses-pinned): GitHub Actions invalid workflow reference means the called workflow is not written in one of three accepted forms. See which form you need and why. - [GitHub Actions job has been skipped (needs)](https://latchkey.dev/learn/github-actions/github-actions-job-skipped-needs-result): A GitHub Actions job has been skipped (needs) because a job it depends on did not succeed. Read the result table, then pick the condition you meant. - [GitHub Actions labeler applies no labels, and which exit you took](https://latchkey.dev/learn/github-actions/gha-labeler-no-labels-applied): When GitHub Actions labeler applies no labels the step is usually red, not green. Find out which of three exits your run took before you edit a glob. - [GitHub Actions matrix exclude not working, and the partial match](https://latchkey.dev/learn/github-actions/gha-matrix-include-exclude-mistakes): GitHub Actions matrix exclude not working usually means it worked too well. An exclude entry matches on the keys it names and ignores the rest. - [GitHub Actions matrix from a JSON file that produces no jobs](https://latchkey.dev/learn/github-actions/gha-matrix-from-json-file-empty): A GitHub Actions matrix from a JSON file rarely fails quietly. Follow the value from the file to the output to the matrix and find where it was lost. - [GitHub Actions matrix include extra job, and the rule that adds it](https://latchkey.dev/learn/github-actions/github-actions-matrix-include-unexpected-combination): A GitHub Actions matrix include extra job is the rule working, not a bug. See how the builder reads each include key and which side yours fell on. - [GitHub Actions Matrix must define at least one vector, and its siblings](https://latchkey.dev/learn/github-actions/gha-matrix-invalid-configuration): GitHub Actions Matrix must define at least one vector is one of five messages the matrix converter can raise. See which block each one is reading. - [GitHub Actions Missing environment production, and what really happens](https://latchkey.dev/learn/github-actions/github-actions-environment-missing-production): GitHub Actions missing environment production is not what a typo produces. Learn what naming an unknown environment actually does to a deploy job. - [GitHub Actions multiline run script fails on the block scalar](https://latchkey.dev/learn/github-actions/github-actions-multiline-run-block-scalar-fails): A GitHub Actions multiline run script fails when the folded block scalar joins your commands. Learn the three YAML rules that decide the text. - [GitHub Actions needs outputs empty between jobs](https://latchkey.dev/learn/github-actions/gha-needs-context-output-undefined): GitHub Actions needs outputs empty is almost always an unmapped step output. Find the four places a value can vanish, then fix the right one. - [GitHub Actions on section missing from a workflow file](https://latchkey.dev/learn/github-actions/github-actions-on-missing-triggers): A GitHub Actions on section missing from a file is fatal even though the published schema does not mark it required. Here is which layer refuses it. - [GitHub Actions paths and paths-ignore together on one event](https://latchkey.dev/learn/github-actions/github-actions-paths-and-paths-ignore-both-set-conflict): Using GitHub Actions paths and paths-ignore together is documented as unsupported, and nothing rejects it. Here is what is published and what is not. - [GitHub Actions pipefail is not on unless you ask for it](https://latchkey.dev/learn/github-actions/github-actions-shell-pipefail-masks-status): GitHub Actions pipefail is only applied when a step says shell: bash. The unspecified default runs bash -e, so a failing pipe passes silently. - [GitHub Actions Process completed with exit code 1, and what stopped](https://latchkey.dev/learn/github-actions/github-actions-run-exit-code-1-set-e): GitHub Actions Process completed with exit code 1 reports the script status, not the reason. See which commands errexit aborts on and which it skips. - [GitHub Actions pwsh command not found on an Ubuntu runner](https://latchkey.dev/learn/github-actions/github-actions-shell-pwsh-not-found-ubuntu): GitHub Actions pwsh command not found comes from the runner looking for the shell, not from a script failing. So there is no exit code to read. - [GitHub Actions Required property is missing: jobs](https://latchkey.dev/learn/github-actions/gha-jobs-section-required): Required property is missing: jobs means the workflow root has no jobs key. Here is what breaks the root mapping and how to read the line. - [GitHub Actions reusable workflow env not inherited by the called file](https://latchkey.dev/learn/github-actions/gha-env-scope-reusable-not-inherited): GitHub Actions reusable workflow env not inherited is by design, and the calling job cannot declare env at all. See what does cross the call boundary. - [GitHub Actions reusable workflow input type mismatch](https://latchkey.dev/learn/github-actions/gha-reusable-input-type-mismatch): Fix a GitHub Actions reusable workflow input type mismatch: the three declared types, the contexts a with block accepts, and the fromJSON cast. - [GitHub Actions reusable workflow outputs empty in the caller](https://latchkey.dev/learn/github-actions/gha-reusable-workflow-outputs-not-surfaced): GitHub Actions reusable workflow outputs empty in the caller means the value was dropped at one of four hops. See which hop, and how to tell them. - [GitHub Actions reusable workflow was not found](https://latchkey.dev/learn/github-actions/gha-reusable-workflow-was-not-found): GitHub Actions reusable workflow was not found means the reference resolved to nothing. Read the arrow chain, then check path, ref and access. - [GitHub Actions run-name env not available, and what it can read](https://latchkey.dev/learn/github-actions/github-actions-env-workflow-level-not-visible-in-run-name): GitHub Actions run-name env not available is a rejected workflow, not a blank title. See the three contexts the key accepts and what to use instead. - [GitHub Actions skipped job required check, and what blocks the merge](https://latchkey.dev/learn/github-actions/github-actions-conditional-job-skipped-marked-failed-branch-protection): A GitHub Actions skipped job required check reports Success and cannot block a merge. See the five look-alike situations and the three that block. - [GitHub Actions stale action processes nothing, or stops early](https://latchkey.dev/learn/github-actions/gha-stale-action-no-issues-processed): When the GitHub Actions stale action processes nothing, the usual cause is a documented limit or a value that means never. Read the four knobs first. - [GitHub Actions step cannot have both uses and run, and what you get](https://latchkey.dev/learn/github-actions/gha-step-cannot-have-uses-and-run): A GitHub Actions step cannot have both uses and run, but the published parser no longer says so. Here is the message it produces now and why. - [GitHub Actions step debug logs truncated, and where the rest is](https://latchkey.dev/learn/github-actions/github-actions-step-debug-logs-truncated): GitHub Actions step debug logs truncated is about the web viewer rather than the stored log. Get the whole thing from the archive instead. - [GitHub Actions step output empty: the missing or misspelled step id](https://latchkey.dev/learn/github-actions/gha-steps-context-missing-step-id): A GitHub Actions step output empty in an expression is a missing id, a misspelled one, a read that runs too early, or a value in another job. - [GitHub Actions submodule checkout failed on a private submodule](https://latchkey.dev/learn/github-actions/checkout-submodule-token-denied): GitHub Actions submodule checkout failed almost always means the token cannot read the submodule repository. See which credential each URL needs. - [GitHub Actions success() and failure() both false after a cancel](https://latchkey.dev/learn/github-actions/github-actions-success-and-failure-both-false-cancelled): GitHub Actions success() and failure() both false is what a four-valued status does to a two-valued test. See what each function compares and when. - [GitHub Actions unable to interpret as boolean: what it really says](https://latchkey.dev/learn/github-actions/github-actions-unable-to-interpret-as-boolean): GitHub Actions unable to interpret as boolean appears in no parser GitHub ships. See where a boolean key raises it, and the case that stays silent. - [GitHub Actions Unable to resolve action, and which half failed](https://latchkey.dev/learn/github-actions/gha-uses-action-not-found): GitHub Actions Unable to resolve action arrives in two forms, and each tells you how far the lookup got before it stopped. Learn to read both. - [GitHub Actions unexpected symbol in a ${{ }} expression](https://latchkey.dev/learn/github-actions/github-actions-unexpected-symbol-expression): Fix GitHub Actions unexpected symbol in a ${{ }} expression: what the parser rejects, where the position points, and the quoting rule behind it. - [GitHub Actions Unexpected Value at a workflow line](https://latchkey.dev/learn/github-actions/github-actions-unexpected-value-line-number): GitHub Actions Unexpected Value names a key or a value the workflow schema did not expect. Read the line, then the branch that rejected it. - [GitHub Actions unexpected value runs-on on a job that cannot have one](https://latchkey.dev/learn/github-actions/gha-unexpected-value-runs-on-in-ci): github actions unexpected value runs-on usually means the job is a reusable-workflow caller, not that the key is indented wrongly. Here is the rule. - [GitHub Actions unexpected value steps, and the file it usually came from](https://latchkey.dev/learn/github-actions/gha-unexpected-value-steps-key-in-ci): github actions unexpected value steps is reported with a column. Column 1 means a whole file from another CI system landed in the workflows directory. - [GitHub Actions Unexpected value true workflow_call, and when it fires](https://latchkey.dev/learn/github-actions/github-actions-reusable-workflow-input-type-mismatch): GitHub Actions Unexpected value true workflow_call is checked in two passes. See which one catches a literal and which waits for the call. - [GitHub Actions unrecognized named-value: env and the context table](https://latchkey.dev/learn/github-actions/gha-bad-expression-context-access): Fix GitHub Actions unrecognized named-value: env with the one table that says which contexts each workflow key will actually resolve a name in. - [GitHub Actions unrecognized named-value: inputs, and the context that is missing](https://latchkey.dev/learn/github-actions/gha-inputs-context-not-available-non-reusable): Fix GitHub Actions unrecognized named-value: inputs, the error that means no trigger in this file ever declared an input for the context to hold. - [GitHub Actions Unrecognized named-value: matrix](https://latchkey.dev/learn/github-actions/github-actions-unrecognized-named-value-matrix): GitHub Actions Unrecognized named-value: matrix means the key you used is not on the matrix context list. Here is that list and the fix. - [GitHub Actions unrecognized named-value: secrets](https://latchkey.dev/learn/github-actions/github-actions-unrecognized-named-value-secrets): GitHub Actions unrecognized named-value: secrets means the context is not offered for that key. See which keys accept it and the ways around it. - [GitHub Actions workflow not found at ref, and the three messages](https://latchkey.dev/learn/github-actions/github-actions-requested-workflow-not-found-at-ref): GitHub Actions workflow not found at ref is a remembered phrase rather than a quotable message. Match what you have against the three real ones. - [GitHub Actions workflow not triggering: three different states](https://latchkey.dev/learn/github-actions/gha-startup-failure): A GitHub Actions workflow not triggering is three different states, and only one of them makes a run. Find out which of the three you are looking at. - [GitHub Actions workflow_dispatch not on default branch](https://latchkey.dev/learn/github-actions/github-actions-workflow-dispatch-not-on-default-branch): GitHub Actions workflow_dispatch not on default branch is why the Run workflow button is missing. Learn the rule, then dispatch any ref you like. - [GitHub Actions working-directory does not exist on the runner](https://latchkey.dev/learn/github-actions/github-actions-working-directory-does-not-exist): When a GitHub Actions working-directory does not exist the step fails before your command runs. The message comes from .NET, not from Actions. - [GitHub Actions working-directory on a uses step is rejected, not ignored](https://latchkey.dev/learn/github-actions/github-actions-working-directory-ignored-by-uses-step): GitHub Actions working-directory on a uses step does not run the action in the wrong folder. The schema has no such key there, so the file is refused. - [GitHub Actions YAML anchors, aliases, and the merge key that is not one](https://latchkey.dev/learn/github-actions/gha-anchor-alias-not-supported): GitHub Actions YAML anchors are documented for GitHub.com, and have been since September 2025. The merge key is not. See what each source says. - [Invalid input, secrets is not defined in the referenced workflow](https://latchkey.dev/learn/github-actions/gha-reusable-secret-not-declared): Invalid input, secrets is not defined in the referenced workflow means a secrets key landed inside with. Read the word after Invalid, then move it. - [Refusing to allow a GitHub App to create or update workflow files](https://latchkey.dev/learn/github-actions/github-actions-app-refuses-workflow-update): Refusing to allow a GitHub App to update a workflow is a push rejection, not a workflow error. See which grant the message names and where it lives. - [The GitHub Actions unexpected input valid inputs are warning](https://latchkey.dev/learn/github-actions/gha-unexpected-inputs-valid-inputs-are): A GitHub Actions unexpected input valid inputs are warning means the runner ignored one of your with keys. Fix the typo before the run goes green. - [Workflow does not have a workflow_dispatch trigger in this branch](https://latchkey.dev/learn/github-actions/github-actions-workflow-dispatch-non-default-branch): Workflow does not have a workflow_dispatch trigger is about the ref you picked, not the default branch. Learn which file GitHub reads on dispatch. - [A GitHub Actions cache-hit output empty value is what a miss looks like](https://latchkey.dev/learn/github-actions/gha-cache-hit-output-not-checked): A GitHub Actions cache-hit output empty value is what a full miss produces. Comparing it against false is why your skip condition never fires. - [actions/setup-node node version file does not exist, and where it looked](https://latchkey.dev/learn/github-actions/actions-setup-node-could-not-resolve-dist-node-version-file): When setup-node node version file does not exist, the path was joined to the workspace root. Read the resolved path before you move the file. - [An artifact with this name already exists in GitHub Actions](https://latchkey.dev/learn/github-actions/gha-artifact-name-already-exists): In GitHub Actions, an artifact with this name already exists is a 409 by design: names are unique per run since v4. Name per leg, or merge after. - [Cache hit occurred on the primary key, and nothing is ever saved again](https://latchkey.dev/learn/github-actions/github-actions-cache-key-collision-immutable-not-updating): Cache hit occurred on the primary key explains a cache that never updates: a static key restores forever and the post step stops writing. - [download-artifact unable to find any artifacts, and why](https://latchkey.dev/learn/github-actions/github-actions-download-artifact-unable-to-find): In GitHub Actions, download-artifact unable to find any artifacts is a version 3 message. Here is what produced it and what version 8 does instead. - [GitHub Actions artifact has expired, and the listing still shows it](https://latchkey.dev/learn/github-actions/gha-artifact-retention-expired): A GitHub Actions artifact has expired failure is a 410 from the download endpoint, not a missing row. The listing still returns the artifact row. - [GitHub Actions Artifact not found for name on download](https://latchkey.dev/learn/github-actions/github-actions-failed-to-download-artifact-not-found): A GitHub Actions Artifact not found for name error is a lookup that came back empty. Check the run it searched before you check the artifact name. - [GitHub Actions artifact upload failed after the files were found](https://latchkey.dev/learn/github-actions/gha-artifact-upload-failed-v4): A GitHub Actions artifact upload failed after the glob succeeded points at one of three API calls. The shape of the message tells you which one. - [GitHub Actions Dependencies lock file is not found in setup-node](https://latchkey.dev/learn/github-actions/gha-setup-node-lock-file-not-found): GitHub Actions Dependencies lock file is not found means setup-node read the repository root and gave up. Point cache-dependency-path at the file. - [GitHub Actions Get Pages site failed in configure-pages](https://latchkey.dev/learn/github-actions/gha-configure-pages-not-enabled): A GitHub Actions Get Pages site failed error is a 404 from the Pages API, not a permissions problem. Read the enablement input before you swap tokens. - [GitHub Actions Path Validation Error caching, on a green job](https://latchkey.dev/learn/github-actions/gha-cache-path-not-found): A GitHub Actions Path Validation Error caching line is written at info level, so the job stays green and no cache is saved. Here is where to find it. - [GitHub Actions reserveCache failed is two different failures](https://latchkey.dev/learn/github-actions/github-actions-cache-reservecache-size-failed): A GitHub Actions reserveCache failed line is assembled at runtime and belongs to the retired v1 cache service. The size refusal is another message. - [Making download-artifact from another workflow run actually work](https://latchkey.dev/learn/github-actions/gha-artifact-download-from-other-run): A download-artifact from another workflow run needs github-token, not run-id. Without the token the action ignores run-id and searches your own run. - [No artifacts named github-pages were found for this workflow run](https://latchkey.dev/learn/github-actions/gha-deploy-pages-artifact-not-found): No artifacts named github-pages were found means deploy-pages searched this run only. The outage line printed underneath it is not your problem. - [No Docker tag has been generated by docker/metadata-action](https://latchkey.dev/learn/github-actions/gha-docker-metadata-action-tags-empty): No Docker tag has been generated means every tag rule declined this event, not that the images input is missing. Read the version warning first. - [No files were found with the provided path in upload-artifact](https://latchkey.dev/learn/github-actions/upload-artifact-no-files-were-found-v4): In GitHub Actions, no files were found with the provided path means the upload glob expanded to nothing. Read the path it printed, then fail loudly. - [The upload-artifact least common ancestor decides your paths](https://latchkey.dev/learn/github-actions/gha-artifact-path-glob-empty): The upload-artifact least common ancestor comes from your search paths, not your matched files. That is why a downloaded artifact is too shallow. - [When actions/upload-pages-artifact path does not exist](https://latchkey.dev/learn/github-actions/upload-pages-artifact-missing): An actions/upload-pages-artifact path does not exist failure comes from tar, not the upload. Find which of the four composite steps went red. - [AADSTS70021 no matching federated identity record found, and its two siblings](https://latchkey.dev/learn/github-actions/oidc-azure-aadsts70021-no-federated-identity-in-ci): aadsts70021 no matching federated identity record found shares its sentence with two other codes. The number, not the words, says what mismatched. - [actions/deploy-pages deployment failed on the github-pages environment](https://latchkey.dev/learn/github-actions/deploy-pages-deployment-failed-environment): An actions/deploy-pages deployment failed at one of three gates, and each gate prints a different line. Find the gate before you edit anything. - [docker/login-action Username and password required error](https://latchkey.dev/learn/github-actions/docker-login-action-username-password-required): docker/login-action Username and password required means both values were empty. The neighboring messages each name one, so the wording is the clue. - [GitHub Actions checkout persisted credentials push 403 in CI](https://latchkey.dev/learn/github-actions/github-actions-checkout-persisted-credentials-403): A GitHub Actions checkout persisted credentials push 403 reuses the credential checkout wrote into git config. The push command is not the fix. - [GitHub Actions composite action cannot access secrets directly](https://latchkey.dev/learn/github-actions/github-actions-composite-action-cannot-access-secrets): A GitHub Actions composite action cannot access secrets: the parser has no such name in that file. The run is rejected before any job starts. - [GitHub Actions environment secrets empty in a job](https://latchkey.dev/learn/github-actions/gha-environment-secrets-not-loaded): GitHub Actions environment secrets empty is not an outage. Environment secrets are read per job, and only for a job that names the environment. - [GitHub Actions ghcr.io push denied and packages: write](https://latchkey.dev/learn/github-actions/github-actions-ghcr-push-denied-packages-write): A GitHub Actions ghcr.io push denied error names the app installation, not you. Four layers restate it, and only the innermost gives a cause. - [GitHub Actions GITHUB_TOKEN cannot access another repository in CI](https://latchkey.dev/learn/github-actions/github-actions-github-token-cannot-access-another-repo): When a GitHub Actions GITHUB_TOKEN cannot access another repository, GitHub answers as though it did not exist. No log line names the boundary. - [GitHub Actions id-token write permission not granted to the job](https://latchkey.dev/learn/github-actions/gha-oidc-id-token-permission): A GitHub Actions id-token write permission not granted issue is about placement. The message is identical wherever the block went, so read the file. - [GitHub Actions input required and not supplied: token error](https://latchkey.dev/learn/github-actions/gha-input-token-required-not-supplied): GitHub Actions input required and not supplied: token is a library check on a variable. The name after the colon is the input, not your secret. - [GitHub Actions job waiting for review on a protected environment](https://latchkey.dev/learn/github-actions/environment-required-reviewers-blocks-deploy-in-ci): A GitHub Actions job waiting for review is held by a protection rule, not failing. Find the rule, find who can clear it, and know the deadline. - [GitHub Actions OIDC failed to get ID token, and the wrapping around it](https://latchkey.dev/learn/github-actions/github-actions-oidc-id-token-error): github actions oidc failed to get id token is the HTTP branch of the toolkit client. It means the request was made, which rules out the usual cause. - [GitHub Actions Pull Request is not mergeable with auto-merge](https://latchkey.dev/learn/github-actions/github-actions-pr-not-mergeable-auto-merge): GitHub Actions Pull Request is not mergeable appears as a step error and as a timeline event, and the two differ in when the state was decided. - [GitHub Actions secrets empty in fork pull requests explained](https://latchkey.dev/learn/github-actions/gha-secret-not-available-fork-pr): GitHub Actions secrets empty in fork pull requests is a documented rule with no error of its own. The first message belongs to whatever used it. - [GitHub Actions waiting for approval to run workflows for this PR](https://latchkey.dev/learn/github-actions/github-actions-waiting-for-approval-pr): GitHub Actions waiting for approval to run workflows is a policy holding a run before dispatch. No job exists yet, and required checks cannot report. - [GITHUB_TOKEN read-only on fork pull requests in GitHub Actions](https://latchkey.dev/learn/github-actions/github-actions-token-push-403-fork): GITHUB_TOKEN read-only on fork pull requests is a documented default, not a broken permissions block. Read the rule, then pick a trigger that writes. - [google-github-actions/auth workload identity audience errors](https://latchkey.dev/learn/github-actions/google-auth-workload-identity-audience): A google-github-actions/auth workload identity audience failure is the first leg, inside the step, and the action names the operation it attempted. - [ncipollo/release-action 403 on release create](https://latchkey.dev/learn/github-actions/ncipollo-release-action-missing-token): ncipollo/release-action 403 on release create means the token arrived and was refused, not that it was missing. Read the status, then fix it. - [OIDC GCP Unable to acquire impersonated credentials in CI](https://latchkey.dev/learn/github-actions/oidc-gcp-unable-to-acquire-impersonated-credentials-in-ci): OIDC GCP Unable to acquire impersonated credentials is raised by a Google library after the auth step passed. The attached body is the real answer. - [peter-evans/create-pull-request 403 and the setting behind it](https://latchkey.dev/learn/github-actions/gha-create-pull-request-token-403): A peter-evans/create-pull-request 403 usually arrives after the branch pushed, which narrows it to one repository setting rather than the token. - [Resource not accessible by personal access token in CI](https://latchkey.dev/learn/github-actions/github-actions-resource-not-accessible-fine-grained-pat): Resource not accessible by personal access token means one permission is missing, not the repository. The response names the endpoint involved. - [secrets: inherit not working in reusable workflows](https://latchkey.dev/learn/github-actions/gha-secrets-inherit-not-forwarded): secrets: inherit not working in reusable workflows has two shapes: one fails the run at startup, the other is silent. Tell them apart first. - [softprops/action-gh-release already_exists on release create](https://latchkey.dev/learn/github-actions/softprops-action-gh-release-validation-failed-already-exists): A softprops/action-gh-release already_exists failure is a race between two jobs on one tag, not a refusal to reuse. The version decides what follows. - [Unable to get ACTIONS_ID_TOKEN_REQUEST_URL in GitHub Actions](https://latchkey.dev/learn/github-actions/github-actions-oidc-id-token-request-url-missing): Unable to get ACTIONS_ID_TOKEN_REQUEST_URL is thrown by the toolkit before any network call, because the runner was never given the variable to read. - [actions/deploy-pages failed to create deployment](https://latchkey.dev/learn/github-actions/github-actions-deploy-pages-action-create-failed): deploy-pages failed to create deployment appends one sentence per HTTP status, and that sentence is the diagnosis. Here is the code that writes it. - [Codecov rate limit reached in GitHub Actions uploads](https://latchkey.dev/learn/github-actions/codecov-action-token-required-rate-limit): Codecov rate limit reached in GitHub Actions means the upload carried no token. Read the token line first: the step stays green either way. - [codecov/codecov-action failed to properly upload report on v4](https://latchkey.dev/learn/github-actions/codecov-action-failed-to-properly-upload-report): codecov/codecov-action failed to properly upload report names the last of three sub-commands. Knowing which one ran tells you what already worked. - [docker/build-push-action failed to solve, and what a missing buildx really prints](https://latchkey.dev/learn/github-actions/docker-build-push-action-buildx-not-set-up): docker/build-push-action failed to solve is a wrapper around a BuildKit error. A missing setup-buildx step prints something else entirely. - [git-auto-commit nothing to commit is two different sentences](https://latchkey.dev/learn/github-actions/stefanzweifel-git-auto-commit-nothing-to-commit): git-auto-commit nothing to commit is the action speaking, not git. The two sentences look alike, come from different programs, and differ in meaning. - [GitHub Actions GITHUB_STEP_SUMMARY too large, and the cap that decides](https://latchkey.dev/learn/github-actions/gha-step-summary-too-large): GitHub Actions GITHUB_STEP_SUMMARY too large is a fixed 1024k cap in the runner. The message reports both numbers, and the step still passes. - [GitHub Actions setup-go unable to find go version, and what is in the quotes](https://latchkey.dev/learn/github-actions/setup-go-unable-to-find-go-version): github actions setup-go unable to find go version quotes the spec it searched for. What sits inside those quotes is the whole diagnosis. - [No pnpm version is specified in pnpm/action-setup](https://latchkey.dev/learn/github-actions/pnpm-action-setup-no-version-specified): No pnpm version is specified means the action looked in three places and found nothing. Here is the order it checks, and the two errors near it. - [No such file or directory @ rb_sysopen on a macOS runner](https://latchkey.dev/learn/github-actions/macos-ruby-rb-sysopen-no-such-file-in-ci): No such file or directory @ rb_sysopen names the C function that failed, not the Ruby line. On macOS runners the caller is usually Homebrew. - [Scheduled workflow disabled after 60 days of inactivity](https://latchkey.dev/learn/github-actions/github-actions-schedule-disabled-60-days-inactivity): A scheduled workflow disabled after 60 days stops firing with no red run to inspect. Confirm the state from the API, re-enable it, keep it awake. - [setup-buildx-action failed to initialize builder is buildx speaking](https://latchkey.dev/learn/github-actions/setup-buildx-failed-to-initialize-builder): setup-buildx-action failed to initialize builder comes from the buildx binary, not the action. The words after the colon are the whole diagnosis. ## Docker in CI: Registry, Build & Runtime - [Docker in CI: Registry, Build & Runtime](https://latchkey.dev/learn/docker): Docker failures that happen in CI: pulls, pushes, auth, BuildKit, runtime and platform mismatches, diagnosed with the exact fix for each one. - [Denied requested access to the resource is denied on push](https://latchkey.dev/learn/docker/docker-denied-requested-access-to-resource-push): Fix denied requested access to the resource is denied on a CI push: one 403 for four situations, and only three are about your token. - [Docker buildx imagetools create failed in CI](https://latchkey.dev/learn/docker/docker-buildx-imagetools-create-failed-in-ci): When docker buildx imagetools create failed in CI, read the stage: source resolution, the copy between repositories, or the final push. - [Docker containerd image store not enabled in CI](https://latchkey.dev/learn/docker/docker-containerd-image-store-not-enabled): Docker containerd image store not enabled is why buildx refuses a multi-platform load, and attestations cause the same refusal on one platform. - [Docker insecure-registries not configured in CI](https://latchkey.dev/learn/docker/docker-insecure-registry-not-configured): Docker insecure-registries not configured is usually an entry that misses, because the daemon matches the host and port as one exact string. - [Docker invalid reference format in CI](https://latchkey.dev/learn/docker/docker-invalid-reference-format-in-ci): Fix Docker invalid reference format in GitHub Actions: the grammar a reference must match, and three ways a workflow builds a name that does not. - [Docker manifest unknown when pulling in CI](https://latchkey.dev/learn/docker/docker-manifest-unknown): Fix docker manifest unknown in GitHub Actions: the repository exists and the reference does not, for one of four reasons the log hides. - [Docker net/http request canceled on a registry call](https://latchkey.dev/learn/docker/docker-net-http-request-canceled-timeout): Docker net/http request canceled on a pull or push is a Go client timeout, and the exact wording says the request never got a connection at all. - [Docker pull access denied repository does not exist in CI](https://latchkey.dev/learn/docker/docker-pull-access-denied-repository-does-not-exist): Fix Docker pull access denied repository does not exist in GitHub Actions: tell a missing name from a private image, and read the newer wording. - [Docker push manifest invalid from a registry](https://latchkey.dev/learn/docker/docker-unsupported-media-type-manifest-push): Fix docker push manifest invalid in CI: the registry names the media type it refused in a detail field that no Docker client prints. - [Docker push to ECR repository does not exist](https://latchkey.dev/learn/docker/docker-ecr-repository-does-not-exist-create): Fix Docker push to ECR repository does not exist in GitHub Actions: create the repo first, or add the template that lets ECR create it during a push. - [Docker unexpected status code from registry in CI](https://latchkey.dev/learn/docker/docker-registry-unexpected-status-code): A docker unexpected status code from registry is not one error: the 5xx wording, the 403 wording and the token wording come from three clients. - [Docker x509 certificate signed by unknown authority in CI](https://latchkey.dev/learn/docker/docker-x509-certificate-signed-by-unknown-authority): Fix Docker x509 certificate signed by unknown authority in GitHub Actions: give the daemon the CA that signed your registry TLS, not an insecure flag. - [Insecure registry HTTP response to HTTPS client in CI](https://latchkey.dev/learn/docker/registry-http-response-to-https-client-in-ci): An insecure registry HTTP response to HTTPS client failure inside a build is BuildKit in a container builder, which does not read the daemon file. - [Docker cannot enter cgroupv2, and cgroup mount errors in CI](https://latchkey.dev/learn/docker/docker-cgroup-cannot-enter-cgroupv2): Fix Docker cannot enter cgroupv2 and the cgroup mount errors in GitHub Actions: delegate the controllers a nested daemon needs, or stop nesting. - [Docker Conflict. The container name is already in use in CI](https://latchkey.dev/learn/docker/docker-container-name-already-in-use): Docker Conflict. The container name is already in use in CI means a container from an earlier step or job still holds it. Learn where it survived. - [Docker device or resource busy, in CI cleanup](https://latchkey.dev/learn/docker/docker-device-or-resource-busy): Fix docker device or resource busy in GitHub Actions: a mount or an open file is holding the path, and the failed cleanup can delete data first. - [Docker error during connect docker_engine in CI](https://latchkey.dev/learn/docker/docker-error-during-connect-named-pipe): Fix Docker error during connect docker_engine on a Windows runner in GitHub Actions: start the engine, fix the context, or move the job to Linux. - [Docker exec user process caused: no such file or directory in CI](https://latchkey.dev/learn/docker/docker-standard-init-linux-exec): Docker exec user process caused: no such file or directory in CI is a missing interpreter or loader, not a missing script. Learn to read which. - [Docker failed to create shim task executable file not found in CI](https://latchkey.dev/learn/docker/docker-failed-to-create-shim-task-not-found): Fix Docker failed to create shim task executable file not found in GitHub Actions: the image cannot run the command it was told to start. - [Docker failed to create shim task runtime error in CI](https://latchkey.dev/learn/docker/docker-failed-to-create-shim-task-in-ci): Docker failed to create shim task runtime error in CI is a chain of wrappers, not a cause. Learn to read the last clause and to fix the right layer. - [Docker failed to set up container networking, on a runner](https://latchkey.dev/learn/docker/docker-failed-to-set-up-container-networking): Fix docker failed to set up container networking in GitHub Actions: the clause after the colon names the real failure, from ports to address pools. - [Docker image does not match the specified platform in CI](https://latchkey.dev/learn/docker/docker-image-platform-mismatch): Docker image does not match the specified platform in CI means a cached single-arch image cannot serve the platform you asked for. Here is the fix. - [Docker mkdir /var/lib/docker: read-only file system in CI](https://latchkey.dev/learn/docker/docker-mkdir-var-lib-docker-read-only-in-ci): Docker mkdir /var/lib/docker: read-only file system in CI means the daemon data root is not writable. Learn to find which mount went read-only. - [Docker OCI runtime error container_linux mkdir /proc in CI](https://latchkey.dev/learn/docker/docker-oci-runtime-mkdir-proc-in-ci): Docker OCI runtime error container_linux mkdir /proc in CI is usually a rootfs mount refusal, not a mkdir. Learn the clause the runtime really emits. - [Docker OCI runtime exec failed](https://latchkey.dev/learn/docker/docker-oci-runtime-exec-failed): Fix Docker OCI runtime exec failed in GitHub Actions: the binary your docker exec named is not in the image, or the container is no longer running. - [Docker permission denied docker.sock on a CI runner](https://latchkey.dev/learn/docker/docker-permission-denied-daemon-socket-in-ci): Docker permission denied docker.sock in CI means the job user cannot open the daemon socket. Learn which group, which user, and which fix lasts. - [Exec user process caused: permission denied in Docker CI](https://latchkey.dev/learn/docker/docker-standard-init-linux-exec-permission-denied-in-ci): Exec user process caused: permission denied in Docker CI is a missing executable bit on the entrypoint, not a user problem. Learn the one-line fix. - [Unable to configure the Docker daemon with file daemon.json in CI](https://latchkey.dev/learn/docker/docker-daemon-json-invalid-failed-to-start): Unable to configure the Docker daemon with file daemon.json stops dockerd before it starts. Learn to read the clause after the file name and fix it. - [Attestation is not supported for the docker driver](https://latchkey.dev/learn/docker/docker-provenance-sbom-attestation-unsupported): Attestation is not supported for the docker driver is one of four separate refusals. Find which program refused your provenance or SBOM build. - [Buildx failed with: failed to receive status](https://latchkey.dev/learn/docker/docker-buildx-failed-to-receive-status): Buildx failed with: failed to receive status is written by the GitHub Action, not by buildx, and the action changed how it builds that line in v7.4.0. - [Docker build lstat permission denied in CI](https://latchkey.dev/learn/docker/docker-lstat-var-lib-docker-permission-in-ci): Docker build lstat permission denied is three programs in one line, and the words lstat and permission denied come from the Go standard library. - [Docker build too many open files in CI](https://latchkey.dev/learn/docker/docker-ulimit-too-many-open-files-build): Docker build too many open files is your program reporting EMFILE, not Docker. Measure the limit inside the step first: it may already be enormous. - [Docker buildx bake failed in CI](https://latchkey.dev/learn/docker/docker-buildx-bake-failed-in-ci): A docker buildx bake failed message comes from one of four layers. Learn to tell an HCL diagnostic from a target lookup, and what bake ignores. - [Docker Compose build must be a string, in CI](https://latchkey.dev/learn/docker/docker-build-services-build-must-be-string-or-object): Docker Compose build must be a string is misleading: a mapping is equally valid. Learn why the validator names only one branch of that rule. - [Docker Compose network declared as external, but not found](https://latchkey.dev/learn/docker/docker-compose-network-declared-external-not-found): Fix docker compose network declared as external in GitHub Actions: Compose never creates one, so create it in the job or let Compose own the network. - [Docker Compose: the attribute version is obsolete, in CI](https://latchkey.dev/learn/docker/docker-compose-version-attribute-obsolete-error-in-ci): Fix docker compose the attribute version is obsolete in GitHub Actions: Compose only warns and exits 0, so the failure is the gate around the step. - [Docker COPY --from stage not found in CI](https://latchkey.dev/learn/docker/docker-copy-from-stage-name-does-not-exist): A docker COPY --from stage not found is not an error at all: BuildKit treats the unknown name as an image and you get a registry denial instead. - [Docker COPY failed: file not found in build context, in CI](https://latchkey.dev/learn/docker/docker-copy-failed-file-not-found-in-ci): Fix docker copy failed: file not found in build context in GitHub Actions: the context, .dockerignore, and the BuildKit wording that names neither. - [Docker dockerfile parse error in CI](https://latchkey.dev/learn/docker/docker-dockerfile-parse-error): A docker dockerfile parse error names a line because one half of the frontend rejected it. The other half fails without that prefix, and differently. - [Docker failed to calculate checksum of ref, in CI](https://latchkey.dev/learn/docker/docker-checksum-file-changed-during-build-in-ci): Docker failed to calculate checksum of ref is the real wording. The compute variant and the file changed during build line are emitted by nothing. - [Docker failed to fetch oauth token during a build](https://latchkey.dev/learn/docker/docker-failed-to-fetch-oauth-token-build): Fix docker failed to fetch oauth token in GitHub Actions: the word in front of token says whether a credential reached the builder at all. - [Docker failed to solve: rpc error: code = Canceled in CI](https://latchkey.dev/learn/docker/docker-failed-to-solve-rpc-error-canceled-in-ci): Docker failed to solve: rpc error: code = Canceled is four programs in one line, and none is reporting a fault. Find who canceled the build. - [Docker invalid file request in CI](https://latchkey.dev/learn/docker/docker-invalid-file-request-path-in-ci): Docker invalid file request is the context transfer protocol losing track of a file, not a path permission or an escape from the build context. - [Docker invalid mount config in CI](https://latchkey.dev/learn/docker/docker-invalid-mount-config-cache-id-in-ci): Docker invalid mount config comes from the daemon validating a container mount. BuildKit cache mounts use different wording, shown here. - [Docker target stage could not be found in CI](https://latchkey.dev/learn/docker/docker-target-stage-not-found): Docker target stage could not be found ignores case in the lookup but not in the hint, so a near miss gets a suggestion and a far one does not. - [Docker: the --mount option requires BuildKit](https://latchkey.dev/learn/docker/docker-mount-requires-buildkit): Fix the --mount option requires buildkit in GitHub Actions: the legacy builder refuses cache and secret mounts, so make the builder explicit. ## Faster GitHub Actions - [Faster GitHub Actions](https://latchkey.dev/learn/speed): Why Actions workflows are slow and the changes that make them fast, with numbers: caching, parallelism, cold starts and Docker build speed. - [Cache Cargo GitHub Actions builds with rust-cache, and its post step](https://latchkey.dev/learn/speed/cache-rust-cargo-in-github-actions): Cache Cargo GitHub Actions builds with Swatinem/rust-cache: what the two keys do, what the post step deletes, and why it can take minutes. - [Cache Go modules GitHub Actions runs, and the file the key changed to](https://latchkey.dev/learn/speed/cache-go-modules-in-github-actions): Cache Go modules GitHub Actions jobs with setup-go: it is on by default, it keys on go.mod since v6.3.0, and it has no restore-keys. - [Cache Gradle GitHub Actions builds, and Maven, with numbers](https://latchkey.dev/learn/speed/cache-gradle-and-maven-in-github-actions): Cache Gradle GitHub Actions builds with setup-gradle and Maven with setup-java, measured cold against warm on one runner, with the keys that hold. - [Cache pip GitHub Actions installs, and Poetry, with numbers](https://latchkey.dev/learn/speed/cache-pip-and-poetry-in-github-actions): Cache pip GitHub Actions installs with setup-python, and why the Poetry virtualenv beats the download cache, measured cold against warm on a runner. - [GitHub Actions cache not restored: the four silent misses](https://latchkey.dev/learn/speed/github-actions-cache-not-restored): Fix a GitHub Actions cache not restored: the key that never repeats, the prefix that matched something stale, and the save that was skipped. - [GitHub Actions cache size limit 10GB: the cap and what it evicts](https://latchkey.dev/learn/speed/github-actions-cache-size-limit): The GitHub Actions cache size limit 10GB default evicts rather than bills. What raising it costs, what eviction takes first, and how to read usage. - [GitHub Actions cache vs artifacts, and the rule that separates them](https://latchkey.dev/learn/speed/github-actions-cache-vs-artifacts): GitHub Actions cache vs artifacts: two storage meters at different rates, two lifetimes, two scopes, and one rule for choosing between them. - [GitHub Actions cache: keys, scopes and the limits that decide a hit](https://latchkey.dev/learn/speed/github-actions-caching-explained): How the GitHub Actions cache matches keys and restore-keys, what the 10 GB cap and the 7-day eviction really do, and when to use an artifact instead. - [Self-hosted GitHub Actions cache server, and the variable it has to win](https://latchkey.dev/learn/speed/self-hosted-github-actions-cache-server): A self-hosted GitHub Actions cache server intercepts actions/cache through one environment variable the runner overwrites on every step. - [Speed up npm install GitHub Actions jobs: what each change is worth](https://latchkey.dev/learn/speed/speed-up-npm-install-in-github-actions): Speed up npm install GitHub Actions jobs with npm ci, the setup-node cache and the right flags, each change measured cold against warm on one runner. - [Why is GitHub Actions slow? Four causes, each measured](https://latchkey.dev/learn/speed/why-is-github-actions-slow): What makes GitHub Actions slow, measured on one job: queue time, the dependency cache, the Docker layer cache and runner size, with every timing. - [GitHub Actions matrix parallel jobs: what each leg really costs](https://latchkey.dev/learn/speed/github-actions-matrix-strategy-parallel-jobs): A GitHub Actions matrix parallel fan-out repeats every fixed cost per leg. How the matrix expands, the ceilings, and where width stops paying. - [GitHub Actions path filters skip jobs, and can block the merge](https://latchkey.dev/learn/speed/github-actions-path-filters-skip-unchanged): GitHub Actions path filters skip jobs whose files did not change. The diff rules, the three limits that reverse them, and the required-check trap. - [GitHub Actions test sharding: how many shards actually pay](https://latchkey.dev/learn/speed/shard-tests-across-github-actions-runners): GitHub Actions test sharding measured: one suite split two and four ways, what a bad split costs, and the arithmetic for when a shard stops paying. - [Parallelize tests by timing, not by file count](https://latchkey.dev/learn/speed/parallelize-tests-by-timing-in-ci): Parallelize tests by timing and the slowest shard stops setting your wall clock: where durations come from, which packer to use, what it is worth. - [Speed up GitHub Actions by avoiding unnecessary work](https://latchkey.dev/learn/speed/skip-unnecessary-work-in-github-actions): Speed up GitHub Actions by avoiding unnecessary work: cancel superseded runs, skip jobs rather than workflows, and cap the ones that hang. - [Split slow test suite CI jobs without losing the test report](https://latchkey.dev/learn/speed/split-a-slow-test-suite-in-ci): To split slow test suite CI jobs you must reassemble the results: unique artifact names, one merge job, combined coverage, one aggregate check. - [GitHub Actions ARM runners: what breaks when you switch](https://latchkey.dev/learn/speed/run-github-actions-on-arm): GitHub Actions ARM runners cost less per minute at every Linux size. What breaks when you switch, how to find it in a week, and how to build images. - [GitHub Actions checkout slow: shallow and sparse clones](https://latchkey.dev/learn/speed/reduce-checkout-time-shallow-sparse-clones): A GitHub Actions checkout slow enough to notice is usually fetch-depth 0, LFS or submodules. What each input downloads, and the filter that helps. - [GitHub Actions runner size: when 2, 4, 8 and 16 vCPU pay off](https://latchkey.dev/learn/speed/choose-a-github-actions-runner-size): Pick a GitHub Actions runner size from one reading in your log. The same work measured on 2 and 4 vCPU, with the rates that decide whether it pays. - [GitHub Actions slow to start: queue time, setup time and the job](https://latchkey.dev/learn/speed/github-actions-cold-start-and-setup-time): Is GitHub Actions slow to start? Separate queue time from setup time, then see what a checkout, a setup action and apt-get really cost, measured. - [actions/cache vs buildx cache: two different systems, measured](https://latchkey.dev/learn/speed/actions-cache-vs-buildx-cache): actions/cache vs buildx cache is not one choice with two spellings. What each stores in GitHub Actions, what each returned, and when each wins. - [Clear the Docker build cache, and what each command cannot reach](https://latchkey.dev/learn/speed/clear-docker-build-cache): Clear docker build cache commands do not all reach the same store. What each prune reclaimed on a GitHub Actions runner, and what clears nothing. - [Docker layer caching in GitHub Actions: which backend, and what it returns](https://latchkey.dev/learn/speed/docker-layer-caching-in-github-actions): Docker layer caching GitHub Actions runners can reuse has to live outside the job. Here is what type=gha, registry and local each returned. - [Docker layer caching not working: read the CACHED count first](https://latchkey.dev/learn/speed/docker-layer-caching-not-working): Docker layer caching GitHub Actions not working? Read the CACHED count, not the clock. Four causes measured on a runner, one quoted from the docs. - [GitHub Actions Docker build slow: six tactics, ranked by result](https://latchkey.dev/learn/speed/speed-up-docker-builds-in-github-actions): A GitHub Actions Docker build slow enough to notice has six plausible fixes. Here is what each one returned on the same image, measured in seconds. - [Reduce Docker image size CI pushes and pulls](https://latchkey.dev/learn/speed/reduce-docker-image-size-for-ci): Reduce Docker image size CI transfers on every run: the measured base image sizes, what multi-stage actually saves, and the layers that never shrink. ## CI for coding agents - [CI for coding agents](https://latchkey.dev/learn/agent-ci): Running CI from Claude Code, Cursor and other agents, and what a runner should hand back to an agent when a job fails. - [CI Doctor GitHub Actions diagnosis, as an open-source skill](https://latchkey.dev/learn/agent-ci/ci-doctor-open-source-ci-diagnosis): CI Doctor GitHub Actions diagnosis packaged as an MIT-licensed agent skill: what it greps, how it classifies a failure, and the catalog behind it. - [Cursor Agent CI and Copilot coding agents, wired into Actions](https://latchkey.dev/learn/agent-ci/ci-for-cursor-and-copilot-coding-agents): Cursor Agent CI runs as a step in your workflow; Copilot brings an environment of its own. What to configure for each, and the gate that holds both. - [How to build a CI failure report for coding agents](https://latchkey.dev/learn/agent-ci/ci-failure-reports-your-agent-can-read): A CI failure report for coding agents is a verdict, one failing step of log and the annotations GitHub already extracted. Here is how to assemble it. - [How to build a coding agent CI pipeline](https://latchkey.dev/learn/agent-ci/give-your-coding-agent-a-ci-runner): A coding agent CI pipeline needs its own trigger, its own runner and its own budget. Four routes to one, with the limit that decides between them. - [How to run CI from Claude Code](https://latchkey.dev/learn/agent-ci/run-github-actions-from-claude-code): Run CI from Claude Code three ways: trigger GitHub Actions with gh, run the steps locally with act, or run the command on a fresh runner. - [How to test AI generated pull requests in CI](https://latchkey.dev/learn/agent-ci/test-ai-generated-pull-requests-in-ci): To test AI generated pull requests in CI, sort them by how they arrived: each shape gets a different token, different secrets, and a different run. - [Run your tests on a fresh runner with latchkey run](https://latchkey.dev/learn/agent-ci/run-tests-on-a-fresh-runner-from-your-terminal): latchkey run tests your working tree on a fresh Ubuntu runner from your terminal, and hands back the log and a verdict before GitHub Actions sees it. - [Self-healing CI vs AI code fixes: which failures belong where](https://latchkey.dev/learn/agent-ci/what-the-runner-fixes-vs-what-your-agent-fixes): Self-healing CI vs AI code fixes is a question about failure class, not capability: which failures a runner absorbs, and which belong to the agent. ## CI Concepts: Reliability, Security & Terms - [CI Concepts: Reliability, Security & Terms](https://latchkey.dev/learn/ci-explained): Self-healing CI, ephemeral runners, reliability, security and the reference pages every GitHub Actions user needs to understand their pipeline. - [A CI/CD pipeline example you can actually run](https://latchkey.dev/learn/ci-explained/ci-cd-pipeline-example): A complete CI/CD pipeline example for GitHub Actions, explained stage by stage, including the gates and cache lines most published examples leave out. - [CI pipeline reliability: what to measure, and what to fix first](https://latchkey.dev/learn/ci-explained/ci-pipeline-reliability-explained): CI pipeline reliability is a ratio, not a pass rate. The four numbers worth tracking on GitHub Actions, and the order to fix your failures in. - [Ephemeral runners explained: one job per machine, and what changes](https://latchkey.dev/learn/ci-explained/ephemeral-runners-explained): Ephemeral runners take one GitHub Actions job and are destroyed. What that changes about caching, secrets and debugging, and how to configure them. - [Exit codes in CI: what every number means and how to fix it](https://latchkey.dev/learn/ci-explained/ci-exit-codes-reference): Exit codes in CI from 0 to 143: what each number means on a GitHub Actions runner, what causes it, and the fix, with the whole table measured on one. - [GitHub Actions deprecations: what breaks, when, and the fix](https://latchkey.dev/learn/ci-explained/github-actions-deprecations-tracker): GitHub Actions deprecations with the date each one takes effect: runner images, moving labels, Node 20 actions and workflow commands, read 2026-09-20. - [GitHub Actions runner specs: vCPU, RAM and disk by size](https://latchkey.dev/learn/ci-explained/github-actions-runner-specs): GitHub Actions runner specs for every size: vCPU, RAM and disk for standard, larger, macOS and ARM runners, with what one real runner measured. - [GitHub Actions security: the controls that actually reduce exposure](https://latchkey.dev/learn/ci-explained/ci-security-github-actions): GitHub Actions security in six controls: token scopes, SHA pins, pull_request_target, fork secrets, OIDC and isolation, with a hardened workflow. - [Self-healing CI, explained: what it repairs and what it must not](https://latchkey.dev/learn/ci-explained/self-healing-ci-explained): Self-healing CI repairs a failing GitHub Actions step mid-job. What it fixes, what it must never touch, and how it differs from a retry. - [What is a GitHub Actions runner, and which kind should run your jobs](https://latchkey.dev/learn/ci-explained/what-is-a-github-actions-runner): What is a GitHub Actions runner? The machine that executes a job: hosted, self-hosted or managed, how runs-on labels pick one, and the job lifecycle. - [What is installed on ubuntu-latest: the GitHub Actions runner image](https://latchkey.dev/learn/ci-explained/whats-installed-on-ubuntu-latest): What is installed on ubuntu-latest today: the GitHub Actions image versions, what is missing, and how to print the list from your own job. ## Industry reports - [The GitHub Actions Cost Index 2026](https://latchkey.dev/learn/reports/github-actions-cost-index-2026): GitHub's published per-minute rates by OS and machine size, eight vendors at one Linux size, and three worked monthly bills. Every figure is dated.