From aa95060f00d7e250164109aa33f56fcfd9b0d8a9 Mon Sep 17 00:00:00 2001 From: Hector Flores Date: Fri, 12 Jun 2026 20:06:42 -0500 Subject: [PATCH] feat: add 3 new error entries (caching-artifacts, runner-environment, silent-failures) --- errors/caching-artifacts/ca-148.yml | 100 ++++++++++++++++++++++ errors/runner-environment/re-490.yml | 120 +++++++++++++++++++++++++++ errors/silent-failures/sf-228.yml | 117 ++++++++++++++++++++++++++ 3 files changed, 337 insertions(+) create mode 100644 errors/caching-artifacts/ca-148.yml create mode 100644 errors/runner-environment/re-490.yml create mode 100644 errors/silent-failures/sf-228.yml diff --git a/errors/caching-artifacts/ca-148.yml b/errors/caching-artifacts/ca-148.yml new file mode 100644 index 0000000..3a325eb --- /dev/null +++ b/errors/caching-artifacts/ca-148.yml @@ -0,0 +1,100 @@ +id: ca-148 +title: '`actions/cache` Fails in Alpine Linux Container — BusyBox `tar` Rejects `-P` Flag' +category: caching-artifacts +severity: error +tags: + - actions-cache + - alpine + - busybox + - tar + - container + - linux + - self-hosted +patterns: + - regex: '/bin/tar: unrecognized option: P' + flags: 'i' + - regex: 'BusyBox.*tar.*unrecognized|unrecognized.*option.*P.*BusyBox' + flags: 'i' + - regex: 'Tar failed with error.*bin/tar.*exit code 1' + flags: 'i' +error_messages: + - "/bin/tar: unrecognized option: P" + - "BusyBox v1.31.1 () multi-call binary." + - "[warning]Tar failed with error: The process '/bin/tar' failed with exit code 1" +root_cause: | + `actions/cache` (v3+) invokes `tar` with the `-P` / `--absolute-names` flag when + creating or extracting cache archives that contain absolute paths. This is a GNU tar + extension that instructs tar to preserve leading slashes. + + Alpine Linux ships **BusyBox tar** as `/bin/tar`, which is a minimal tar implementation + that does not support the GNU `-P` (`--absolute-names`) flag. When the cache action + calls `/bin/tar ... -P ...`, BusyBox exits immediately with: + + ``` + /bin/tar: unrecognized option: P + BusyBox v1.31.1 () multi-call binary. + [warning]Tar failed with error: The process '/bin/tar' failed with exit code 1 + ``` + + This causes both cache save and cache restore to fail silently (the workflow continues, + but the cache is never persisted or retrieved). + + The issue has been present since actions/cache introduced zstd compression with + absolute-path support and was re-reported in actions/cache#1765 (June 2026) as a + re-open of the original actions/cache#352. +fix: | + Install GNU tar in the Alpine container before the `actions/cache` step. BusyBox tar + must be replaced or overridden so that `/bin/tar` refers to the full GNU implementation. + + **Option 1 — Install `tar` package in Alpine (recommended):** + + ```yaml + - name: Install GNU tar + run: apk add --no-cache tar + ``` + + After `apk add tar`, Alpine's `/bin/tar` is replaced by GNU tar which supports `-P`. + + **Option 2 — Use a non-Alpine base image that ships GNU tar:** + + Prefer `ubuntu:24.04`, `debian:bookworm-slim`, or similar images where GNU tar is + present by default. + + **Option 3 — Disable compression fallback (partial workaround):** + + Some versions of `actions/cache` respect `SEGMENT_DOWNLOAD_TIMEOUT_MINS` or a `tar-*` + environment variable. Check if setting `CACHE_COMPRESSION=gzip` (if supported in your + version) avoids the `-P` flag. This is undocumented and version-dependent. +fix_code: + - language: yaml + label: "Install GNU tar before actions/cache in Alpine container" + code: | + jobs: + build: + runs-on: ubuntu-latest + container: + image: alpine:3.19 + steps: + - name: Install GNU tar (required for actions/cache) + run: apk add --no-cache tar + + - name: Restore cache + uses: actions/cache@v4 + with: + path: ~/.cache + key: ${{ runner.os }}-cache-${{ hashFiles('**/lockfiles') }} + + - name: Build + run: make build +prevention: + - "Always install GNU tar (`apk add --no-cache tar`) as an early step when using `actions/cache` in Alpine-based containers." + - "Test your full workflow in an Alpine container locally before relying on CI caching — BusyBox tar failures are silent (the workflow succeeds but the cache is never populated)." + - "Consider using `ubuntu-latest` or a Debian-based runner/container image to avoid BusyBox compatibility issues with Actions that expect GNU coreutils." + - "When using container jobs on self-hosted runners, verify the tar binary version with `tar --version` — GNU tar will print 'GNU tar' while BusyBox will not." +docs: + - url: "https://github.com/actions/cache/issues/1765" + label: "actions/cache#1765: Post cache not working on Alpine runners (2026 re-open)" + - url: "https://github.com/actions/cache/issues/352" + label: "actions/cache#352: Original Alpine / BusyBox tar compatibility issue" + - url: "https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/caching-dependencies-to-speed-up-workflows" + label: "GitHub Docs: Caching dependencies to speed up workflows" diff --git a/errors/runner-environment/re-490.yml b/errors/runner-environment/re-490.yml new file mode 100644 index 0000000..179ae6c --- /dev/null +++ b/errors/runner-environment/re-490.yml @@ -0,0 +1,120 @@ +id: re-490 +title: '`actions/setup-node` Fails When `.yarnrc.yml` Contains Yarn v4.14 `approvedGitRepositories` Key' +category: runner-environment +severity: error +tags: + - setup-node + - yarn + - yarnrc + - cache + - approvedGitRepositories + - yarn-berry + - node + - caching +patterns: + - regex: 'Unrecognized or legacy configuration settings found: approvedGitRepositories' + flags: 'i' + - regex: 'The .yarn config get cacheFolder. command failed with exit code: 1' + flags: 'i' + - regex: 'approvedGitRepositories.*run.*yarn config -v' + flags: 'i' +error_messages: + - "Usage Error: Unrecognized or legacy configuration settings found: approvedGitRepositories - run \"yarn config -v\" to see the list of settings supported in Yarn" + - "Error: The 'yarn config get cacheFolder' command failed with exit code: 1" +root_cause: | + `actions/setup-node` detects the active package manager at setup time. When `cache: 'yarn'` + is enabled (or auto-detected), it probes the Yarn cache folder by running: + + ``` + yarn config get cacheFolder + ``` + + Yarn v4.14 introduced `approvedGitRepositories` as a new top-level configuration key in + `.yarnrc.yml` to control which Git repositories can be used as package sources. If the + project's `.yarnrc.yml` declares `approvedGitRepositories`, but the `yarn` binary that + `setup-node` invokes is an older version that does not recognize this key, Yarn aborts + config command execution with: + + ``` + Usage Error: Unrecognized or legacy configuration settings found: approvedGitRepositories + ``` + + and exits with code 1. `setup-node` then fails with: + + ``` + Error: The 'yarn config get cacheFolder' command failed with exit code: 1 + ``` + + The failure can manifest as an infinite retry loop (setup-node calls `yarn config get` + multiple times) before ultimately erroring out, wasting several minutes of job time. +fix: | + Choose the fix that best fits your situation: + + **Option 1 — Pin a matching yarn version in `setup-node` (recommended):** + Add `yarn-version: '4.14.1'` (or latest) so setup-node installs a Yarn binary that + understands `approvedGitRepositories` before it probes the cache folder. + + ```yaml + - uses: actions/setup-node@v6 + with: + node-version: '20' + cache: 'yarn' + # yarn-version is not a native setup-node input; use corepack instead: + - run: corepack enable && corepack prepare yarn@4.14.1 --activate + ``` + + **Option 2 — Enable corepack to auto-install the correct Yarn version first:** + + ```yaml + - run: corepack enable + - uses: actions/setup-node@v6 + with: + node-version: '20' + cache: 'yarn' + ``` + + With corepack enabled, the `yarn` invocation during setup resolves from the + `packageManager` field in `package.json`, which should be `yarn@4.14.x`. + + **Option 3 — Disable yarn cache detection in setup-node and manage cache manually:** + + ```yaml + - uses: actions/setup-node@v6 + with: + node-version: '20' + # no cache: 'yarn' — skip the cacheFolder probe + - name: Get Yarn cache directory + id: yarn-cache-dir + run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT + - uses: actions/cache@v4 + with: + path: ${{ steps.yarn-cache-dir.outputs.dir }} + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + ``` +fix_code: + - language: yaml + label: "Use corepack to activate the correct Yarn version before setup-node" + code: | + steps: + - uses: actions/checkout@v6 + + - name: Enable Corepack (installs yarn from package.json#packageManager) + run: corepack enable + + - uses: actions/setup-node@v6 + with: + node-version: '20' + cache: 'yarn' + + - run: yarn install --immutable +prevention: + - "Always pin your Yarn version in `package.json` via the `packageManager` field (e.g., `\"packageManager\": \"yarn@4.14.1\"`) and enable corepack so all tooling uses the same binary." + - "When adding new `.yarnrc.yml` keys introduced in a specific Yarn version, ensure your CI pipeline installs that Yarn version before any step that invokes `yarn config` (including setup-node's auto-detection)." + - "Run `yarn --version` as a debug step when setup-node fails during yarn cache detection to confirm which yarn binary was being invoked." +docs: + - url: "https://github.com/actions/setup-node/issues/1534" + label: "actions/setup-node#1534: Problem with yarn v4.14 config approvedGitRepositories" + - url: "https://yarnpkg.com/configuration/yarnrc#approvedGitRepositories" + label: "Yarn Berry docs: approvedGitRepositories configuration" + - url: "https://github.com/actions/setup-node#caching-packages-dependencies" + label: "actions/setup-node: Caching package dependencies" diff --git a/errors/silent-failures/sf-228.yml b/errors/silent-failures/sf-228.yml new file mode 100644 index 0000000..ec4f792 --- /dev/null +++ b/errors/silent-failures/sf-228.yml @@ -0,0 +1,117 @@ +id: sf-228 +title: '`softprops/action-gh-release` v2.6 Converts Existing Release to Draft and Fails to Finalize New Release' +category: silent-failures +severity: error +tags: + - action-gh-release + - softprops + - release + - github-release + - tag + - overwrite + - draft + - finalize +patterns: + - regex: 'error finalizing release.*already_exists.*tag_name' + flags: 'i' + - regex: 'HttpError: Validation Failed.*Release.*already_exists.*tag_name' + flags: 'i' + - regex: 'Using release \d+ for tag .+ instead of duplicate draft \d+' + flags: 'i' +error_messages: + - "error finalizing release: HttpError: Validation Failed: {\"resource\":\"Release\",\"code\":\"already_exists\",\"field\":\"tag_name\"}" + - "retrying... (2 retries remaining)" + - "retrying... (1 retries remaining)" +root_cause: | + In `softprops/action-gh-release` v2.6.x, the release creation logic has a race condition + when creating a release for a tag that already has an existing published release and the + workflow deletes and re-creates the tag (common in nightly/rolling release patterns). + + The sequence that causes the silent corruption: + + 1. Workflow deletes the existing tag and immediately re-creates it at the new commit. + 2. The action finds TWO release objects associated with the nightly tag: + - The **old published release** (which GitHub keeps associated with the deleted tag) + - A newly-created **draft release** generated in a prior race window + 3. The action logs: `Using release for tag instead of duplicate draft ` + and selects the older published release to update. + 4. While processing, the action **converts the old published release to draft** status + as part of an internal update step — without surfacing this to the user. + 5. The action then attempts to create/finalize a new release and fails with: + ``` + error finalizing release: HttpError: Validation Failed: + {"resource":"Release","code":"already_exists","field":"tag_name"} + ``` + because the tag still points to the converted-to-draft old release. + 6. After 3 retries the workflow fails — leaving the repository with a **draft release** + (the converted old one) and no published release for that tag. + + This is a silent failure because subscriber emails fire when the old release is briefly + republished (step 4 side-effect), but then the release disappears when it reverts to + draft status — causing user confusion and empty release page state. +fix: | + **Option 1 — Pin to `v2.5.x` (immediate fix):** + + Downgrade to the last stable version before v2.6 regressions: + + ```yaml + - uses: softprops/action-gh-release@v2.5.0 + with: + tag_name: nightly + prerelease: true + files: dist/* + ``` + + **Option 2 — Pre-delete the release before re-creating the tag:** + + Use the GitHub CLI to explicitly delete the existing release before the tag + delete/recreate sequence, eliminating the duplicate-draft race: + + ```yaml + - name: Delete existing release + run: | + gh release delete nightly --yes --cleanup-tag || true + env: + GH_TOKEN: ${{ github.token }} + + - uses: softprops/action-gh-release@v2.6.1 + with: + tag_name: nightly + prerelease: true + files: dist/* + ``` +fix_code: + - language: yaml + label: "Stable rolling nightly release using gh CLI pre-deletion" + code: | + - name: Delete previous nightly release and tag + run: | + gh release delete nightly --yes --cleanup-tag 2>/dev/null || true + env: + GH_TOKEN: ${{ github.token }} + + - name: Create new nightly release + uses: softprops/action-gh-release@v2.5.0 + with: + tag_name: nightly + name: "Nightly Build ${{ github.sha }}" + prerelease: true + generate_release_notes: false + files: | + dist/Windows-*.zip + dist/Linux-*.AppImage + dist/MacOS-*.zip + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} +prevention: + - "For rolling releases (nightly, latest), always delete the existing release with `gh release delete --yes --cleanup-tag` before tag re-creation to avoid the duplicate-draft race." + - "Pin action versions in workflows — use `softprops/action-gh-release@v2.5.0` or a pinned SHA until the v2.6 race condition is fixed upstream." + - "Audit release workflows after Dependabot bumps `softprops/action-gh-release` — the v2.5 → v2.6 upgrade is silent and introduces this race condition." + - "Monitor the Releases page for releases unexpectedly converting to draft status after a workflow run — this is the first symptom of this bug." +docs: + - url: "https://github.com/softprops/action-gh-release/issues/772" + label: "softprops/action-gh-release#772: Draft release gets created, and empty release gets published (v2.6.1)" + - url: "https://github.com/softprops/action-gh-release/releases" + label: "softprops/action-gh-release releases" + - url: "https://docs.github.com/en/rest/releases/releases#update-a-release" + label: "GitHub REST API: Update a release"