@htekdev/actions-debugger 1.0.123 → 1.0.125

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/errors/caching-artifacts/caching-artifacts-073.yml +100 -0
  2. package/errors/caching-artifacts/caching-artifacts-074.yml +117 -0
  3. package/errors/known-unsolved/known-unsolved-070.yml +83 -0
  4. package/errors/known-unsolved/known-unsolved-071.yml +122 -0
  5. package/errors/known-unsolved/known-unsolved-072.yml +143 -0
  6. package/errors/permissions-auth/permissions-auth-071.yml +144 -0
  7. package/errors/permissions-auth/permissions-auth-072.yml +112 -0
  8. package/errors/permissions-auth/permissions-auth-073.yml +127 -0
  9. package/errors/permissions-auth/permissions-auth-074.yml +106 -0
  10. package/errors/permissions-auth/permissions-auth-075.yml +137 -0
  11. package/errors/runner-environment/runner-environment-224.yml +74 -0
  12. package/errors/runner-environment/runner-environment-225.yml +85 -0
  13. package/errors/runner-environment/runner-environment-226.yml +91 -0
  14. package/errors/runner-environment/runner-environment-227.yml +106 -0
  15. package/errors/runner-environment/runner-environment-228.yml +117 -0
  16. package/errors/runner-environment/runner-environment-229.yml +119 -0
  17. package/errors/runner-environment/runner-environment-230.yml +129 -0
  18. package/errors/runner-environment/runner-environment-231.yml +90 -0
  19. package/errors/runner-environment/runner-environment-232.yml +131 -0
  20. package/errors/runner-environment/runner-environment-233.yml +90 -0
  21. package/errors/runner-environment/runner-environment-234.yml +114 -0
  22. package/errors/runner-environment/runner-environment-235.yml +151 -0
  23. package/errors/silent-failures/silent-failures-112.yml +97 -0
  24. package/errors/silent-failures/silent-failures-113.yml +110 -0
  25. package/errors/silent-failures/silent-failures-114.yml +116 -0
  26. package/errors/silent-failures/silent-failures-115.yml +130 -0
  27. package/errors/silent-failures/silent-failures-116.yml +117 -0
  28. package/errors/silent-failures/silent-failures-117.yml +137 -0
  29. package/errors/silent-failures/silent-failures-118.yml +156 -0
  30. package/errors/yaml-syntax/yaml-syntax-075.yml +128 -0
  31. package/errors/yaml-syntax/yaml-syntax-076.yml +107 -0
  32. package/package.json +1 -1
@@ -0,0 +1,129 @@
1
+ id: runner-environment-230
2
+ title: 'setup-python installs free-threaded Python (3.13t / 3.14t) as broken 0-byte symlink on windows-11-arm64'
3
+ category: runner-environment
4
+ severity: error
5
+ tags:
6
+ - setup-python
7
+ - free-threaded
8
+ - python-3.13t
9
+ - python-3.14t
10
+ - windows-11-arm64
11
+ - symlink
12
+ - arm64
13
+ - GIL
14
+ patterns:
15
+ - regex: 'Remove-Item.+arm64-freethreaded.+python\.exe.+because it does not exist'
16
+ flags: 'i'
17
+ - regex: 'Fatal Python error: Failed to import encodings module'
18
+ flags: 'i'
19
+ - regex: 'ModuleNotFoundError: No module named .encodings.'
20
+ flags: 'i'
21
+ - regex: 'Error happened during pip installation / upgrade'
22
+ flags: 'i'
23
+ error_messages:
24
+ - "[error] Remove-Item : Cannot find path 'C:\\hostedtoolcache\\windows\\Python\\3.13.3-freethreaded\\arm64-freethreaded\\python.exe' because it does not exist."
25
+ - '[error] Fatal Python error: Failed to import encodings module'
26
+ - '[error] ModuleNotFoundError: No module named ''encodings'''
27
+ - '[error] Error happened during pip installation / upgrade'
28
+ root_cause: |
29
+ The `win32-arm64-freethreaded` distribution zip for Python 3.13t and 3.14t
30
+ contains `python.exe` and `python3.exe` as **symlinks** (Windows reparse
31
+ points) that point to the version-specific binary (e.g. `python3.13t.exe`).
32
+
33
+ When `actions/setup-python` extracts the zip to the tool cache, the symlink
34
+ target does not exist at the expected relative path inside the extracted
35
+ directory. This leaves `python.exe` and `python3.exe` as **dangling 0-byte
36
+ reparse points** rather than working executables.
37
+
38
+ The setup script (`setup.ps1`, line 131) then attempts to remove `python.exe`
39
+ before placing the shim — but because the file is a dangling reparse point,
40
+ PowerShell cannot find it and throws:
41
+
42
+ `Remove-Item : Cannot find path '...\arm64-freethreaded\python.exe'
43
+ because it does not exist.`
44
+
45
+ Even if this error is swallowed, any subsequent attempt to invoke the
46
+ interpreter fails because the `python.exe` reparse point has no valid target.
47
+ The interpreter cannot locate its standard library, resulting in:
48
+
49
+ `Fatal Python error: Failed to import encodings module`
50
+
51
+ Non-free-threaded arm64 builds (`3.11`, `3.12`, `3.13`) are NOT affected
52
+ because their zips contain real executable files rather than symlinks.
53
+ x64 free-threaded builds are also unaffected.
54
+
55
+ This bug is present in `actions/setup-python` v5.x and v6.x when
56
+ `windows-11-arm64` runners are used. It was reported in April 2026 and
57
+ assigned for fix; check actions/setup-python#1307 for the patched release.
58
+ fix: |
59
+ **Workaround 1 (recommended until patched):** Use a non-arm64 runner for
60
+ free-threaded Python testing. The x64 free-threaded wheels work correctly on
61
+ `windows-latest` or `windows-2025`:
62
+
63
+ ```yaml
64
+ runs-on: windows-latest # x64 runner
65
+ ```
66
+
67
+ **Workaround 2:** Install free-threaded Python from NuGet on arm64 runners
68
+ rather than using `actions/setup-python`:
69
+
70
+ ```powershell
71
+ nuget install Microsoft.Python.Python.3.13-freethreaded.Arm64 -Version 3.13.3 -OutputDirectory .python
72
+ ```
73
+
74
+ **Workaround 3:** If you need arm64 + free-threaded specifically, test on
75
+ a Linux arm64 runner (`ubuntu-24.04-arm`) where the free-threaded build
76
+ does not have the symlink issue.
77
+
78
+ **Long-term:** Upgrade to the patched `actions/setup-python` version once
79
+ released (track actions/setup-python#1307).
80
+ fix_code:
81
+ - language: yaml
82
+ label: 'Run free-threaded Python tests on x64 instead of arm64 until fix ships'
83
+ code: |
84
+ jobs:
85
+ test-freethreaded:
86
+ # Use x64 runner — free-threaded Python on windows-11-arm64 is broken
87
+ # (setup-python#1307). Switch back when the fix ships.
88
+ runs-on: windows-latest
89
+ steps:
90
+ - uses: actions/checkout@v4
91
+ - uses: actions/setup-python@v6
92
+ with:
93
+ python-version: '3.13t' # free-threaded; works on x64
94
+ - run: python --version
95
+ - run: python -c "import sys; print(sys._is_gil_enabled())"
96
+ - language: yaml
97
+ label: 'Use a matrix to run standard Python on arm64 and free-threaded on x64'
98
+ code: |
99
+ jobs:
100
+ test:
101
+ strategy:
102
+ matrix:
103
+ include:
104
+ # Standard arm64 — works fine
105
+ - os: windows-11-arm64
106
+ python-version: '3.13'
107
+ # Free-threaded — x64 only until setup-python#1307 is fixed
108
+ - os: windows-latest
109
+ python-version: '3.13t'
110
+ runs-on: ${{ matrix.os }}
111
+ steps:
112
+ - uses: actions/checkout@v4
113
+ - uses: actions/setup-python@v6
114
+ with:
115
+ python-version: ${{ matrix.python-version }}
116
+ prevention:
117
+ - 'When adding free-threaded Python (3.13t, 3.14t) to a matrix, verify the runner OS — windows-11-arm64 has a broken symlink issue; use windows-latest (x64) instead.'
118
+ - 'Pin actions/setup-python to a known-good version and monitor actions/setup-python#1307 for the fix release before upgrading on arm64 free-threaded jobs.'
119
+ - 'After setting up free-threaded Python, add a smoke-test step (`python -c "import sys; print(sys.version)"`) early in the job to catch a broken interpreter before the full test suite runs.'
120
+ - 'Check that python.exe in the tool cache is a real executable, not a 0-byte reparse point, by running `(Get-Item python.exe).Length -gt 0` in a PowerShell step on windows-arm64.'
121
+ docs:
122
+ - url: 'https://github.com/actions/setup-python/issues/1307'
123
+ label: 'actions/setup-python#1307 — setup-python fails for free-threaded Python (3.13t / 3.14t) on windows-11-arm64'
124
+ - url: 'https://github.com/onnx/onnx/actions/runs/24930991133'
125
+ label: 'Example failing CI run (onnx/onnx)'
126
+ - url: 'https://docs.python.org/3/whatsnew/3.13.html#free-threaded-cpython'
127
+ label: 'Python 3.13 — Free-threaded CPython (experimental no-GIL build)'
128
+ - url: 'https://github.com/actions/setup-python'
129
+ label: 'actions/setup-python — GitHub repository'
@@ -0,0 +1,90 @@
1
+ id: runner-environment-231
2
+ title: 'setup-java hangs indefinitely at "Trying to resolve the latest version from remote"'
3
+ category: runner-environment
4
+ severity: error
5
+ tags:
6
+ - setup-java
7
+ - version-resolution
8
+ - hang
9
+ - network
10
+ - JDK
11
+ - distribution
12
+ - timeout
13
+ - temurin
14
+ patterns:
15
+ - regex: 'Trying to resolve the latest version from remote'
16
+ flags: 'i'
17
+ - regex: 'setup-java.+Trying to resolve.+version'
18
+ flags: 'i'
19
+ error_messages:
20
+ - 'Trying to resolve the latest version from remote'
21
+ root_cause: |
22
+ When `java-version` is specified without a full patch version (e.g., `'21'`
23
+ or `'17'`), `actions/setup-java` must contact the JDK distribution's upstream
24
+ release manifest API to resolve the latest matching release. Before the fix
25
+ added in later versions of the action, this HTTP request was issued without a
26
+ timeout. When the upstream distribution endpoint (Eclipse Temurin, Amazon
27
+ Corretto, Microsoft JDK, etc.) was slow or unreachable — even transiently —
28
+ the resolution step could stall indefinitely, wedging the job until the
29
+ workflow-level `timeout-minutes` expired.
30
+
31
+ This affected all distributions that require a remote lookup for the latest
32
+ version, and was particularly impactful in environments with restricted or
33
+ intermittently degraded outbound network connectivity. The action would print
34
+ "Trying to resolve the latest version from remote" and then produce no further
35
+ output until the job hit its overall timeout.
36
+
37
+ The root cause was reported with 24+ community reactions in
38
+ actions/setup-java#897. The action was subsequently updated with improved
39
+ retry logic and enhanced error messages that surface the endpoint being
40
+ queried, making failures diagnosable.
41
+ fix: |
42
+ **Immediate workaround (always recommended):** Pin an explicit full or
43
+ three-part version to bypass the remote manifest lookup entirely:
44
+
45
+ ```yaml
46
+ - uses: actions/setup-java@v4
47
+ with:
48
+ java-version: '21.0.3' # Explicit patch version — no remote resolution needed
49
+ distribution: 'temurin'
50
+ ```
51
+
52
+ **Alternative:** Upgrade `actions/setup-java` to the version that includes
53
+ retry/timeout improvements (v4.2.2 or later). The updated action adds
54
+ timeouts and surfaces the endpoint URL in error output so stalls are
55
+ diagnosable rather than silent hangs.
56
+
57
+ **For self-hosted runners with restricted outbound access:** Explicitly add
58
+ the JDK distribution manifest endpoints to your allowlist, or pin exact
59
+ versions to eliminate remote lookups entirely.
60
+ fix_code:
61
+ - language: yaml
62
+ label: 'Pin explicit patch version to avoid remote resolution'
63
+ code: |
64
+ - name: Set up JDK 21
65
+ uses: actions/setup-java@v4
66
+ with:
67
+ # Explicit 3-part version — skips "Trying to resolve the latest
68
+ # version from remote" entirely
69
+ java-version: '21.0.3'
70
+ distribution: 'temurin'
71
+ - language: yaml
72
+ label: 'Use version file to avoid hardcoding version while skipping remote lookup'
73
+ code: |
74
+ # Define your JDK version in .java-version or .tool-versions
75
+ # When java-version-file is present, no remote lookup is needed:
76
+ - name: Set up JDK
77
+ uses: actions/setup-java@v4
78
+ with:
79
+ java-version-file: '.java-version'
80
+ distribution: 'temurin'
81
+ prevention:
82
+ - 'Always pin an explicit JDK patch version (e.g., 21.0.3) or use a version file to eliminate remote manifest lookups and prevent hang-on-stall failures.'
83
+ - 'Set `timeout-minutes` on individual steps or jobs so a stalled remote lookup kills the step quickly rather than consuming the full runner allocation.'
84
+ - 'Monitor outbound network connectivity from self-hosted runners to JDK distribution APIs (e.g., api.adoptium.net for Temurin) and add these endpoints to firewall/proxy allowlists.'
85
+ - 'Use `actions/setup-java@v4.2.2` or later which includes retry logic and improved error messages for remote resolution failures.'
86
+ docs:
87
+ - url: 'https://github.com/actions/setup-java/issues/897'
88
+ label: 'actions/setup-java#897 — Trying to resolve the latest version from remote (indefinite hang)'
89
+ - url: 'https://github.com/actions/setup-java#supported-version-syntax'
90
+ label: 'actions/setup-java — Supported version syntax (pin exact versions to avoid remote lookup)'
@@ -0,0 +1,131 @@
1
+ id: runner-environment-232
2
+ title: 'Self-hosted runner started as a service (svc.sh/svc.cmd) does not load user PATH from shell profile'
3
+ category: runner-environment
4
+ severity: error
5
+ tags:
6
+ - self-hosted
7
+ - PATH
8
+ - svc.sh
9
+ - service
10
+ - environment-variables
11
+ - bash
12
+ - profile
13
+ - command-not-found
14
+ patterns:
15
+ - regex: '(?:command not found|No such file or directory).+(?:\/home\/.+\/|~\/.+\/|GOPATH|cargo\/bin|\.local\/bin)'
16
+ flags: 'i'
17
+ - regex: '(?:bash|sh):.+: (?:command not found|No such file or directory)'
18
+ flags: 'i'
19
+ error_messages:
20
+ - '/bin/bash: my-tool: command not found'
21
+ - 'bash: /home/runner/.local/bin/my-tool: No such file or directory'
22
+ - 'Error: Unable to locate executable file: my-tool. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable.'
23
+ root_cause: |
24
+ When the self-hosted runner is registered and started as a system service
25
+ using `svc.sh install && svc.sh start` (Linux/macOS) or
26
+ `svc.cmd install` (Windows), the service is launched by the OS service
27
+ manager (systemd, launchd, or Windows SCM) rather than interactively by
28
+ the user. As a result:
29
+
30
+ 1. **Shell profile files are NOT sourced.** The service process never runs
31
+ `~/.bashrc`, `~/.bash_profile`, `~/.profile`, or `~/.zshrc`, so any
32
+ `export PATH=...` statements in those files have no effect on the runner
33
+ process or any job steps it spawns.
34
+
35
+ 2. **Step shells use `--noprofile --norc` by default.** Even when job steps
36
+ invoke `bash`, the runner uses `bash --noprofile --norc -e -o pipefail`
37
+ (or equivalent), which explicitly disables sourcing of profile files.
38
+ This means binaries installed in user-specific directories — such as
39
+ `~/.local/bin`, `~/.cargo/bin`, `~/go/bin`, `~/.nvm/versions/node/*/bin`,
40
+ or any path added via `nvm`, `rbenv`, `pyenv`, `asdf`, etc. — are missing
41
+ from `PATH` in job steps even if they work fine in an interactive terminal.
42
+
43
+ 3. **The runner's `.env` file is the authoritative PATH source.** The runner
44
+ process reads environment variables from a `.env` file at startup
45
+ (typically at `<runner-install-dir>/.env`). This file is NOT automatically
46
+ populated when the service is installed.
47
+
48
+ This is a common trap when developers install tools as their user (e.g.,
49
+ `cargo install`, `npm install -g`, `go install`, `pip install --user`) and
50
+ then register a self-hosted runner. Everything works in an interactive
51
+ terminal but fails when the service-started runner tries to execute the same
52
+ commands.
53
+ fix: |
54
+ **Option 1 (recommended): Add paths to the runner's `.env` file**
55
+ Edit `<runner-install-dir>/.env` and append the needed PATH entries. The
56
+ runner reads this file at startup and merges it into the environment for all
57
+ job steps:
58
+
59
+ ```bash
60
+ # Append to <runner-install-dir>/.env
61
+ PATH=/home/runner/.cargo/bin:/home/runner/.local/bin:/home/runner/go/bin:$PATH
62
+ ```
63
+
64
+ Restart the service after editing: `sudo svc.sh stop && sudo svc.sh start`
65
+
66
+ **Option 2: Use `$GITHUB_PATH` in the workflow**
67
+ Add a step early in the job to append the needed paths using the
68
+ `$GITHUB_PATH` mechanism — this persists for all subsequent steps in the job:
69
+
70
+ ```yaml
71
+ - name: Add user bins to PATH
72
+ run: echo "$HOME/.local/bin" >> $GITHUB_PATH
73
+ ```
74
+
75
+ **Option 3: Start the runner interactively (development/testing only)**
76
+ Use `./run.sh` instead of the service to start the runner in an interactive
77
+ session that sources your shell profile. This is useful for debugging but
78
+ not suitable for production.
79
+
80
+ **Option 4: Change step shell to a login shell**
81
+ Override the shell at the step level to source the user profile:
82
+
83
+ ```yaml
84
+ - name: Run with login shell
85
+ shell: 'bash --login -e {0}'
86
+ run: my-tool --version
87
+ ```
88
+ fix_code:
89
+ - language: yaml
90
+ label: 'Append user bin paths to runner PATH via .env file (persistent, affects all jobs)'
91
+ code: |
92
+ # Run this once on the self-hosted runner host:
93
+ # echo "PATH=/home/runner/.cargo/bin:/home/runner/.local/bin:$PATH" >> /home/runner/actions-runner/.env
94
+ # Then restart the runner service: sudo ./svc.sh stop && sudo ./svc.sh start
95
+ #
96
+ # In your workflow, the tool will now be found without any PATH workaround:
97
+ - name: Use cargo-installed tool
98
+ run: my-tool --version
99
+ - language: yaml
100
+ label: 'Append missing path per-job using $GITHUB_PATH'
101
+ code: |
102
+ jobs:
103
+ build:
104
+ runs-on: [self-hosted, linux]
105
+ steps:
106
+ - name: Add cargo bin to PATH
107
+ run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH
108
+
109
+ - name: Use cargo-installed tool
110
+ run: my-tool --version # Now visible because GITHUB_PATH was updated
111
+ - language: yaml
112
+ label: 'Use login shell on a single step to source ~/.profile'
113
+ code: |
114
+ - name: Run with login shell (sources ~/.profile and ~/.bash_profile)
115
+ shell: 'bash --login -e {0}'
116
+ run: |
117
+ my-tool --version
118
+ prevention:
119
+ - 'After registering a self-hosted runner, verify PATH by running a debug step: `run: echo $PATH && which my-tool` to confirm expected binaries are visible.'
120
+ - 'Document all non-standard tool paths in your `.env` file at runner registration time, before registering as a service, so PATH is correct from the first job.'
121
+ - 'Prefer system-wide tool installations (e.g., `/usr/local/bin/`) over user-specific paths for tools used on self-hosted runners, so the service environment sees them without profile sourcing.'
122
+ - 'When using version managers like nvm, rbenv, pyenv, or asdf, their shims are typically installed into shell-profile-sourced directories and will NOT work in service-started runners without explicit PATH entries in `.env`.'
123
+ docs:
124
+ - url: 'https://github.com/actions/runner/issues/2903'
125
+ label: 'actions/runner#2903 — Runner service does not update PATH when started via svc.sh'
126
+ - url: 'https://github.com/actions/runner/issues/2528'
127
+ label: 'actions/runner#2528 — PATH changes at runtime not applied to runner steps (--noprofile --norc)'
128
+ - url: 'https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners#adding-the-runner-to-your-enterprise'
129
+ label: 'GitHub Docs — Self-hosted runner environment configuration'
130
+ - url: 'https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#adding-a-system-path'
131
+ label: 'GitHub Docs — Adding a system path (GITHUB_PATH)'
@@ -0,0 +1,90 @@
1
+ id: runner-environment-233
2
+ title: 'actions/checkout < v6.0.3 fails on SHA-256 repositories — fatal: mismatched algorithms: client sha1; server sha256'
3
+ category: runner-environment
4
+ severity: error
5
+ tags:
6
+ - checkout
7
+ - sha256
8
+ - git
9
+ - object-format
10
+ - hash-algorithm
11
+ - repository
12
+ - v6
13
+ patterns:
14
+ - regex: 'fatal: mismatched algorithms: client sha1; server sha256'
15
+ flags: 'i'
16
+ - regex: 'fatal: mismatched algorithms: client sha256; server sha1'
17
+ flags: 'i'
18
+ - regex: 'mismatched algorithms.*sha1.*sha256'
19
+ flags: 'i'
20
+ error_messages:
21
+ - 'fatal: mismatched algorithms: client sha1; server sha256'
22
+ - "The process '/usr/bin/git' failed with exit code 128"
23
+ root_cause: |
24
+ GitHub is progressively rolling out support for SHA-256 object-format repositories
25
+ (also called NewHash or sha256-mode repos). When a repository is SHA-256-mode,
26
+ every git object reference is a 64-character hex SHA-256 hash instead of the
27
+ traditional 40-character SHA-1 hash.
28
+
29
+ Before actions/checkout v6.0.3, the checkout action always initialised the local
30
+ working-tree repository with a plain `git init`, which defaults to SHA-1 object
31
+ format. When the action then attempts to `git fetch` from a SHA-256 remote, git
32
+ detects that the local and remote repositories use different hash algorithms and
33
+ immediately aborts:
34
+
35
+ fatal: mismatched algorithms: client sha1; server sha256
36
+
37
+ The mismatch is unrecoverable — the local repository must be created with
38
+ `git init --object-format=sha256` BEFORE the first fetch. There is no in-place
39
+ conversion.
40
+
41
+ This only affects workflows where the target GitHub repository has been migrated
42
+ to or created as SHA-256 mode. GitHub began rolling out SHA-256 repository creation
43
+ in late 2025; adoption will grow over time. Previously-created SHA-1 repositories
44
+ are unaffected until they are explicitly migrated.
45
+
46
+ The fix shipped in actions/checkout v6.0.3 (June 2, 2026, commit 1cce339).
47
+ It calls the GitHub REST endpoint `GET /repos/{owner}/{repo}/hash-algorithm`
48
+ before `git init` and passes `--object-format=sha256` when the repository is
49
+ SHA-256 mode.
50
+
51
+ Source: actions/checkout#2160, PR#2439.
52
+ fix: |
53
+ Upgrade to actions/checkout@v6.0.3 or later. Version v6.0.3 detects the
54
+ repository's object format via the GitHub API before initialising the local
55
+ git repository and passes the correct `--object-format` flag to `git init`.
56
+
57
+ If you cannot upgrade immediately, set the GIT_DEFAULT_HASH environment variable
58
+ to sha256 before running checkout, then reinitialise manually — but upgrading
59
+ the action is strongly preferred.
60
+
61
+ Note: v6.0.3 introduced a new REST API call (`GET /repos/.../hash-algorithm`) on
62
+ every checkout, which can cause secondary rate-limit issues for organisations with
63
+ very high parallel job counts. See runner-environment-206 for that separate issue.
64
+ fix_code:
65
+ - language: yaml
66
+ label: 'Upgrade to actions/checkout v6.0.3+ to fix SHA-256 repository support'
67
+ code: |
68
+ - uses: actions/checkout@v6.0.3
69
+ with:
70
+ fetch-depth: 1
71
+ - language: yaml
72
+ label: 'Pin to v6.0.3+ by SHA for reproducibility (recommended for security-sensitive workflows)'
73
+ code: |
74
+ # Pin to the exact commit SHA of v6.0.3 to lock the version
75
+ - uses: actions/checkout@1cce3390c2bfda521930d01229c073c7ff920824 # v6.0.3
76
+ with:
77
+ fetch-depth: 1
78
+ prevention:
79
+ - 'Always pin to a specific patch version of actions/checkout (e.g., @v6.0.3) rather than a floating major tag (@v6), so breaking changes from new GitHub repository features land on your own schedule'
80
+ - 'If your organisation creates new repositories, check whether SHA-256 mode is the default; SHA-256 repos will silently break all workflows using checkout < v6.0.3'
81
+ - 'Monitor the actions/checkout changelog when upgrading; v6.0.3 also introduced a new API call that can affect rate limits in high-parallelism environments (see runner-environment-206)'
82
+ docs:
83
+ - url: 'https://github.com/actions/checkout/issues/2160'
84
+ label: 'actions/checkout#2160 — hashing mismatch error on SHA-256 repository'
85
+ - url: 'https://github.com/actions/checkout/pull/2439'
86
+ label: 'actions/checkout PR#2439 — Fix checkout init for SHA-256 repositories (merged June 2026)'
87
+ - url: 'https://github.com/actions/checkout/releases/tag/v6.0.3'
88
+ label: 'actions/checkout v6.0.3 release — SHA-256 repository support'
89
+ - url: 'https://git-scm.com/docs/hash-function-transition'
90
+ label: 'Git documentation — SHA-256 hash function transition'
@@ -0,0 +1,114 @@
1
+ id: runner-environment-234
2
+ title: "actions/checkout v6 credential helper overrides embedded PAT in cross-repo git push — 403 Permission denied to github-actions[bot]"
3
+ category: runner-environment
4
+ severity: error
5
+ tags:
6
+ - checkout
7
+ - v6
8
+ - credential-helper
9
+ - cross-repo
10
+ - PAT
11
+ - git-push
12
+ - extraheader
13
+ - 403
14
+ - permission-denied
15
+ patterns:
16
+ - regex: 'remote: Permission to .+\.git denied to github-actions\[bot\]'
17
+ flags: 'i'
18
+ - regex: 'fatal: unable to access .+github\.com.+: The requested URL returned error: 403'
19
+ flags: 'i'
20
+ - regex: 'Permission denied to github-actions\[bot\]\.'
21
+ flags: 'i'
22
+ error_messages:
23
+ - 'remote: Permission to owner/nightly-releases.git denied to github-actions[bot].'
24
+ - 'fatal: unable to access ''https://github.com/owner/repo/'': The requested URL returned error: 403'
25
+ root_cause: |
26
+ When a workflow uses actions/checkout v6 and then manually adds a second git remote
27
+ whose URL embeds a Personal Access Token (PAT), the cross-repo git push fails with
28
+ a 403 even though the PAT is valid and has the required scope.
29
+
30
+ actions/checkout injects a GitHub token (GITHUB_TOKEN by default) into the local
31
+ git configuration as an HTTP Authorization header for `https://github.com/` URLs
32
+ via `http.https://github.com/.extraheader`. A common pattern to push to a separate
33
+ repository using a PAT is to:
34
+ 1. Add a remote with the PAT embedded in the URL:
35
+ git remote add nightly_repo https://TOKEN@github.com/owner/repo.git
36
+ 2. Remove the checkout-injected extraheader to prevent it from conflicting:
37
+ git config --unset-all http.https://github.com/.extraheader
38
+ 3. Push via the PAT URL remote.
39
+
40
+ This pattern worked correctly with actions/checkout v4 and v5. In v6, the sequence
41
+ fails because the action now also registers a git credential helper
42
+ (`credential.https://github.com.helper`) alongside the extraheader. When the
43
+ extraheader is manually unset in step 2, the credential helper remains configured.
44
+ Git consults the credential helper for all `https://github.com/` requests —
45
+ including the push to the PAT URL remote — and the helper returns GITHUB_TOKEN
46
+ (authenticated as `github-actions[bot]`). This token overrides the PAT embedded
47
+ in the remote URL, and since `github-actions[bot]` does not have write access to
48
+ the target repository, the push fails with HTTP 403.
49
+
50
+ The root distinction from earlier versions: unsetting `http.extraheader` alone is
51
+ no longer sufficient to fully remove checkout's credential injection in v6.
52
+
53
+ Source: actions/checkout#2424 (April 2026, open).
54
+ fix: |
55
+ **Option 1 (recommended): Use `persist-credentials: false` in checkout.**
56
+ This prevents checkout from configuring any git credentials at all. The subsequent
57
+ git push uses the PAT embedded in the remote URL without interference.
58
+
59
+ **Option 2: Explicitly clear the credential helper after checkout.**
60
+ After the checkout step, unset both the extraheader AND the credential helper:
61
+ git config --unset-all http.https://github.com/.extraheader || true
62
+ git config --global --unset credential.https://github.com.helper || true
63
+ git config --global --unset credential.helper || true
64
+
65
+ Note: the exact helper key may vary; inspect `git config --list` to see all keys
66
+ set by checkout before unsetting.
67
+
68
+ **Option 3: Provide the PAT via the checkout `token:` input instead.**
69
+ If the PAT has access to both the primary repo and the target cross-repo, pass it
70
+ as the `token:` input so checkout configures it as the credential for all
71
+ github.com pushes. This avoids the need to inject a second credential entirely.
72
+ fix_code:
73
+ - language: yaml
74
+ label: 'Recommended: use persist-credentials: false and embed PAT in remote URL'
75
+ code: |
76
+ - uses: actions/checkout@v6
77
+ with:
78
+ persist-credentials: false # prevents checkout from injecting any git credentials
79
+
80
+ - name: Push tags to nightly releases repository
81
+ env:
82
+ NIGHTLY_PAT: ${{ secrets.NIGHTLY_PAT }}
83
+ run: |
84
+ git remote add nightly_repo \
85
+ "https://${NIGHTLY_PAT}@github.com/owner/nightly-releases.git"
86
+ git tag -f nightly
87
+ git push -f nightly_repo nightly
88
+ - language: yaml
89
+ label: 'Alternative: pass PAT to checkout token: input (when PAT has access to primary repo)'
90
+ code: |
91
+ - uses: actions/checkout@v6
92
+ with:
93
+ # If CROSS_REPO_PAT has access to the checked-out repo as well,
94
+ # checkout will configure it for all github.com credential requests.
95
+ token: ${{ secrets.CROSS_REPO_PAT }}
96
+
97
+ - name: Push tags to nightly releases repository
98
+ run: |
99
+ git remote add nightly_repo \
100
+ "https://${{ secrets.CROSS_REPO_PAT }}@github.com/owner/nightly-releases.git"
101
+ git tag -f nightly
102
+ git push -f nightly_repo nightly
103
+ prevention:
104
+ - 'Use `persist-credentials: false` in any checkout step that is followed by a cross-repo git push using a PAT, to avoid checkout credential helpers interfering with the push'
105
+ - 'When debugging 403 errors on git push, check `git config --list` to see all credential-related configuration; look for any helper or extraheader keys referencing github.com'
106
+ - 'Avoid relying on unsetting only `http.https://github.com/.extraheader` to remove checkout credentials in v6+; the set of keys checkout writes has changed across versions'
107
+ - 'When migrating from actions/checkout v4/v5 to v6, test all workflows that manually manipulate git credentials or push to cross-repo remotes'
108
+ docs:
109
+ - url: 'https://github.com/actions/checkout/issues/2424'
110
+ label: 'actions/checkout#2424 — Unable to create tags in another repo with v6 (403 Permission denied)'
111
+ - url: 'https://github.com/actions/checkout#usage'
112
+ label: 'actions/checkout README — persist-credentials input'
113
+ - url: 'https://docs.github.com/en/actions/security-for-github-actions/security-guides/automatic-token-authentication'
114
+ label: 'GitHub Docs — GITHUB_TOKEN automatic token authentication'