@htekdev/actions-debugger 1.0.113 → 1.0.115
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.
- package/errors/caching-artifacts/cache-corrupt-on-cancel-during-restore-save-always.yml +136 -0
- package/errors/caching-artifacts/restore-keys-asterisk-literal-not-glob.yml +107 -0
- package/errors/concurrency-timing/concurrency-timing-053.yml +83 -0
- package/errors/concurrency-timing/pull-request-review-shared-concurrency-cancels-ci.yml +131 -0
- package/errors/known-unsolved/github-script-esm-not-supported.yml +111 -0
- package/errors/known-unsolved/job-outputs-string-only-no-array-object.yml +142 -0
- package/errors/known-unsolved/known-unsolved-062.yml +87 -0
- package/errors/known-unsolved/runner-rest-api-busy-false-broker-state-desync.yml +102 -0
- package/errors/permissions-auth/oidc-immutable-sub-claim-new-repo-trust-policy-mismatch.yml +122 -0
- package/errors/permissions-auth/permissions-auth-064.yml +122 -0
- package/errors/permissions-auth/permissions-auth-065.yml +97 -0
- package/errors/permissions-auth/permissions-auth-066.yml +129 -0
- package/errors/permissions-auth/upload-code-coverage-missing-code-quality-write-permission.yml +94 -0
- package/errors/runner-environment/arc-kubernetes-checkout-circular-json-container-hook.yml +101 -0
- package/errors/runner-environment/cache-restore-windows-runner-silent-crash.yml +130 -0
- package/errors/runner-environment/git-248-fetch-tags-shallow-clone-regression.yml +100 -0
- package/errors/runner-environment/javascript-actions-alpine-arm64-not-supported.yml +121 -0
- package/errors/runner-environment/runner-environment-188.yml +96 -0
- package/errors/runner-environment/runner-environment-191.yml +147 -0
- package/errors/runner-environment/runner-environment-192.yml +144 -0
- package/errors/runner-environment/runner-environment-193.yml +136 -0
- package/errors/runner-environment/runner-environment-194.yml +86 -0
- package/errors/runner-environment/runner-environment-199.yml +93 -0
- package/errors/runner-environment/setup-python-macos-self-hosted-symlink-permission-denied.yml +94 -0
- package/errors/runner-environment/setup-python-windows-self-hosted-no-admin-install-fails.yml +101 -0
- package/errors/silent-failures/checkout-v6-clean-false-deletes-workspace-on-repo-change.yml +119 -0
- package/errors/silent-failures/queue-max-silently-ignored-with-cancel-in-progress.yml +109 -0
- package/errors/silent-failures/silent-failures-102.yml +141 -0
- package/errors/silent-failures/silent-failures-104.yml +119 -0
- package/errors/triggers/triggers-069.yml +100 -0
- package/errors/yaml-syntax/continue-on-error-inputs-composite-action-unexpected-value.yml +110 -0
- package/errors/yaml-syntax/yaml-syntax-068.yml +137 -0
- package/errors/yaml-syntax/yaml-syntax-069.yml +118 -0
- package/package.json +1 -1
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
id: runner-environment-194
|
|
2
|
+
title: 'Job Blocked at Queue: "recent account payments have failed or your spending limit needs to be increased"'
|
|
3
|
+
category: runner-environment
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- billing
|
|
7
|
+
- spending-limit
|
|
8
|
+
- payments
|
|
9
|
+
- job-blocked
|
|
10
|
+
- queue
|
|
11
|
+
- account
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: 'recent account payments have failed'
|
|
14
|
+
flags: 'i'
|
|
15
|
+
- regex: 'spending limit needs to be increased'
|
|
16
|
+
flags: 'i'
|
|
17
|
+
- regex: 'The job was not started because recent account'
|
|
18
|
+
flags: 'i'
|
|
19
|
+
error_messages:
|
|
20
|
+
- "The job was not started because recent account payments have failed or your spending limit needs to be increased."
|
|
21
|
+
root_cause: |
|
|
22
|
+
GitHub Actions computes minutes and storage usage against the account or organization's
|
|
23
|
+
spending limit. When either of the following conditions is true, queued jobs are never
|
|
24
|
+
assigned a runner and remain stuck indefinitely:
|
|
25
|
+
|
|
26
|
+
1. **Billing failure** — the payment method on file was declined or has expired. GitHub
|
|
27
|
+
cannot charge for overages and blocks new job starts as a safeguard.
|
|
28
|
+
|
|
29
|
+
2. **Spending limit reached** — the account spending limit for Actions minutes (or
|
|
30
|
+
artifact/package storage) has been hit. The default spending limit for paid plans is
|
|
31
|
+
$0 of overage; once included minutes are exhausted, jobs are blocked unless the limit
|
|
32
|
+
is raised.
|
|
33
|
+
|
|
34
|
+
The error message appears in the workflow run summary and the job queue-wait log — NOT in
|
|
35
|
+
step output, because no step ever runs. Jobs remain at "Queued" and eventually time out
|
|
36
|
+
(typically 6 hours) with this message.
|
|
37
|
+
|
|
38
|
+
Common triggers:
|
|
39
|
+
- End of billing cycle — included minutes exhausted, spending limit at $0
|
|
40
|
+
- Payment method expired (credit card expiry, bank decline, insufficient funds)
|
|
41
|
+
- Free plan runner-minutes exhausted mid-month with no spending limit override
|
|
42
|
+
- Organization suspended or billing contact unreachable
|
|
43
|
+
fix: |
|
|
44
|
+
**For payment failure:**
|
|
45
|
+
1. Navigate to Settings → Billing and plans → Payment information
|
|
46
|
+
2. Update or replace the payment method
|
|
47
|
+
3. Re-run failed workflow jobs after billing resolves
|
|
48
|
+
|
|
49
|
+
**For spending limit exhaustion:**
|
|
50
|
+
1. Navigate to Settings → Billing and plans → Spending limits
|
|
51
|
+
2. Set a non-zero spending limit for Actions (or increase the existing limit)
|
|
52
|
+
3. Alternatively, migrate expensive workloads to self-hosted runners to eliminate
|
|
53
|
+
billed minute consumption
|
|
54
|
+
|
|
55
|
+
**Check current usage:**
|
|
56
|
+
- Settings → Billing and plans → View usage this month → Actions
|
|
57
|
+
fix_code:
|
|
58
|
+
- language: yaml
|
|
59
|
+
label: "Route expensive jobs to self-hosted runner to avoid billed minutes"
|
|
60
|
+
code: |
|
|
61
|
+
jobs:
|
|
62
|
+
build:
|
|
63
|
+
# Self-hosted runners consume $0 of GitHub-hosted Actions minutes
|
|
64
|
+
runs-on: self-hosted
|
|
65
|
+
steps:
|
|
66
|
+
- uses: actions/checkout@v4
|
|
67
|
+
- run: npm run build
|
|
68
|
+
- language: yaml
|
|
69
|
+
label: "Reduce billed minutes with cancel-in-progress concurrency"
|
|
70
|
+
code: |
|
|
71
|
+
# Cancel stale runs on new push — saves minutes on abandoned branches
|
|
72
|
+
concurrency:
|
|
73
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
74
|
+
cancel-in-progress: true
|
|
75
|
+
prevention:
|
|
76
|
+
- "Set a non-zero spending limit or configure spending alerts in Settings → Billing to receive email warnings before jobs are blocked"
|
|
77
|
+
- "Monitor Actions usage in Settings → Billing and plans → Usage this month on a regular cadence"
|
|
78
|
+
- "Use `cancel-in-progress: true` concurrency groups to cancel stale workflow runs automatically and reduce minute consumption"
|
|
79
|
+
- "For high-parallelism CI, use self-hosted runners or larger runner credits (Teams/Enterprise) to avoid mid-month exhaustion"
|
|
80
|
+
docs:
|
|
81
|
+
- url: "https://docs.github.com/en/billing/managing-billing-for-your-products/managing-billing-for-github-actions/about-billing-for-github-actions"
|
|
82
|
+
label: "About billing for GitHub Actions"
|
|
83
|
+
- url: "https://docs.github.com/en/billing/managing-billing-for-your-products/managing-billing-for-github-actions/managing-your-spending-limit-for-github-actions"
|
|
84
|
+
label: "Managing your spending limit for GitHub Actions"
|
|
85
|
+
- url: "https://github.com/orgs/community/discussions/151956"
|
|
86
|
+
label: "GitHub Community Discussion #151956 — jobs not starting due to spending limit"
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
id: runner-environment-199
|
|
2
|
+
title: 'Windows self-hosted runner V2 broker listener stops polling after first job (2.334.0)'
|
|
3
|
+
category: runner-environment
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- self-hosted
|
|
7
|
+
- windows
|
|
8
|
+
- runner-v2
|
|
9
|
+
- broker
|
|
10
|
+
- listener
|
|
11
|
+
- stuck
|
|
12
|
+
- message-queue
|
|
13
|
+
- v2-flow
|
|
14
|
+
patterns:
|
|
15
|
+
- regex: 'Get messages has been cancelled using local token source\. Continue to get messages with new status'
|
|
16
|
+
flags: 'i'
|
|
17
|
+
- regex: 'BrokerMessageListener.*cancel|cancel.*BrokerMessageListener'
|
|
18
|
+
flags: 'i'
|
|
19
|
+
error_messages:
|
|
20
|
+
- 'Get messages has been cancelled using local token source. Continue to get messages with new status.'
|
|
21
|
+
root_cause: |
|
|
22
|
+
On Windows self-hosted runners running v2.334.0 with the V2 broker flow enabled
|
|
23
|
+
(`useV2Flow: true`, connecting to `broker.actions.githubusercontent.com`), the
|
|
24
|
+
`BrokerMessageListener` stops issuing GET /message requests after the first job
|
|
25
|
+
completes and the runner transitions from Busy→Online (idle).
|
|
26
|
+
|
|
27
|
+
The root cause is a race condition in the V2 state machine reset path: when the
|
|
28
|
+
Busy→Online transition fires, the existing `localTokenSource` for the polling loop
|
|
29
|
+
is cancelled (logging "Get messages has been cancelled using local token source.
|
|
30
|
+
Continue to get messages with new status."), but the replacement polling loop fails
|
|
31
|
+
to start due to a missing null-check or async continuation bug on Windows. OAuth
|
|
32
|
+
token refreshes continue normally (masking the hang — credentials are not the issue),
|
|
33
|
+
but no new GET /message requests are dispatched.
|
|
34
|
+
|
|
35
|
+
The runner UI shows the runner as "Idle" indefinitely. Any jobs queued after the
|
|
36
|
+
first run sit in "Queued" status and never start until the runner service is manually
|
|
37
|
+
restarted. The issue is specific to Windows (the identical code path on Linux/macOS
|
|
38
|
+
appears unaffected) and requires a service start + exactly one job completion to
|
|
39
|
+
trigger. Reproduced reliably across multiple self-hosted Windows environments.
|
|
40
|
+
|
|
41
|
+
Reported against runner v2.334.0, commit f1995ede5d885c997d13d8eca5467c4ce97fe69c.
|
|
42
|
+
No fix available as of June 2026. Open at actions/runner#4444.
|
|
43
|
+
fix: |
|
|
44
|
+
Immediate workaround: restart the runner service after each job, or add an automated
|
|
45
|
+
watchdog that monitors the runner diagnostics log for the stale-listener pattern and
|
|
46
|
+
triggers a service restart.
|
|
47
|
+
|
|
48
|
+
Longer-term: downgrade to runner v2.333.x until actions/runner#4444 is resolved.
|
|
49
|
+
Check the runner release notes for a fix targeting the V2 BrokerMessageListener
|
|
50
|
+
state-reset path.
|
|
51
|
+
fix_code:
|
|
52
|
+
- language: yaml
|
|
53
|
+
label: 'PowerShell watchdog snippet to restart runner service on listener hang (add to a monitoring script)'
|
|
54
|
+
code: |
|
|
55
|
+
# Watchdog: detect stale BrokerMessageListener and restart runner service
|
|
56
|
+
# Run this as a scheduled task every 5 minutes on the runner host
|
|
57
|
+
|
|
58
|
+
$diagDir = "C:\actions-runner\_diag"
|
|
59
|
+
$logFile = Get-ChildItem $diagDir -Filter "Runner_*.log" | Sort-Object LastWriteTime -Descending | Select-Object -First 1
|
|
60
|
+
$lastMsg = (Get-Content $logFile.FullName -Tail 200 | Select-String "BrokerMessageListener") | Select-Object -Last 1
|
|
61
|
+
|
|
62
|
+
# If the last BrokerMessageListener log entry is the cancellation message
|
|
63
|
+
# and it's more than 10 minutes old, restart the service
|
|
64
|
+
if ($lastMsg -match "cancelled using local token source") {
|
|
65
|
+
$entryTime = [datetime]::Parse(($lastMsg -split " ")[0])
|
|
66
|
+
if ((Get-Date) - $entryTime -gt [TimeSpan]::FromMinutes(10)) {
|
|
67
|
+
Restart-Service actions.runner.*
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
- language: yaml
|
|
71
|
+
label: 'Pin runner version to 2.333.x in ARC or self-hosted runner config'
|
|
72
|
+
code: |
|
|
73
|
+
# For ARC (Actions Runner Controller) — pin runner version in values.yaml
|
|
74
|
+
githubConfigSecret: pre-defined-secret
|
|
75
|
+
template:
|
|
76
|
+
spec:
|
|
77
|
+
containers:
|
|
78
|
+
- name: runner
|
|
79
|
+
env:
|
|
80
|
+
- name: RUNNER_VERSION
|
|
81
|
+
value: "2.333.0" # Pin below 2.334.0 until #4444 is fixed
|
|
82
|
+
prevention:
|
|
83
|
+
- "Subscribe to the actions/runner release feed to catch regression fixes; downgrade immediately when a V2-flow listener regression is reported."
|
|
84
|
+
- "For Windows runner pools, add a service watchdog (Task Scheduler or Prometheus alert) that detects listener staleness via the _diag/Runner_*.log pattern."
|
|
85
|
+
- "Consider switching to ephemeral JIT runners on Windows — ephemeral runners cannot hit this bug because each runner handles exactly one job then exits."
|
|
86
|
+
- "Monitor runner queue depth in your autoscaler; an idle runner with > 0 queued jobs is a reliable signal the listener has stalled."
|
|
87
|
+
docs:
|
|
88
|
+
- url: 'https://github.com/actions/runner/issues/4444'
|
|
89
|
+
label: 'actions/runner#4444 — Listener stops polling broker after first job (2.334.0, Windows, V2 flow)'
|
|
90
|
+
- url: 'https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners'
|
|
91
|
+
label: 'About self-hosted runners'
|
|
92
|
+
- url: 'https://github.com/actions/runner/releases'
|
|
93
|
+
label: 'Actions Runner release notes'
|
package/errors/runner-environment/setup-python-macos-self-hosted-symlink-permission-denied.yml
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
id: runner-environment-198
|
|
2
|
+
title: 'setup-python fails on macOS self-hosted runner with "ln: python3XX: Permission denied" — symlink created without sudo after sudo install'
|
|
3
|
+
category: runner-environment
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- setup-python
|
|
7
|
+
- self-hosted
|
|
8
|
+
- macos
|
|
9
|
+
- symlink
|
|
10
|
+
- permissions
|
|
11
|
+
- sudo
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: 'ln:.*python3\d+.*Permission denied'
|
|
14
|
+
flags: 'i'
|
|
15
|
+
- regex: 'Error:.*ln:.*python.*Permission denied'
|
|
16
|
+
flags: 'i'
|
|
17
|
+
error_messages:
|
|
18
|
+
- 'Error: ln: python314: Permission denied'
|
|
19
|
+
- 'Error: ln: python312: Permission denied'
|
|
20
|
+
- 'Error: ln: python313: Permission denied'
|
|
21
|
+
root_cause: |
|
|
22
|
+
The setup-python macOS installer script (setup.sh) uses sudo to install the Python
|
|
23
|
+
framework into /Library/Frameworks/ — a root-owned directory. However, the
|
|
24
|
+
subsequent step that creates symlinks inside that directory (e.g., linking
|
|
25
|
+
python3.14 → python3) runs WITHOUT sudo, causing a permission error when the
|
|
26
|
+
runner''s CI user is a standard (non-root) account even if sudo is available for
|
|
27
|
+
the install step.
|
|
28
|
+
|
|
29
|
+
The error appears as:
|
|
30
|
+
Error: ln: python314: Permission denied
|
|
31
|
+
|
|
32
|
+
This affects macOS self-hosted runners (EC2, bare-metal, VM) where the runner
|
|
33
|
+
service is configured as a non-admin user. GitHub-hosted macOS runners are
|
|
34
|
+
unaffected because they grant passwordless sudo to the runner user.
|
|
35
|
+
|
|
36
|
+
A fix was proposed in actions/python-versions PR #384 to use sudo for the symlink
|
|
37
|
+
creation step as well, but is not yet merged/released as of mid-2026.
|
|
38
|
+
fix: |
|
|
39
|
+
Short-term workaround: Grant the runner service user passwordless sudo on the
|
|
40
|
+
macOS runner machine, or run the runner as a user with write access to
|
|
41
|
+
/Library/Frameworks/ and /usr/local/bin.
|
|
42
|
+
|
|
43
|
+
Safer workaround: Pre-install Python on the macOS runner machine using the
|
|
44
|
+
official Python.org pkg installer (which creates symlinks correctly as root), then
|
|
45
|
+
rely on setup-python''s PATH-detection to use the pre-installed version without
|
|
46
|
+
invoking the installer.
|
|
47
|
+
|
|
48
|
+
Enterprise workaround: Use a custom RUNNER_TOOL_CACHE path that is owned by the
|
|
49
|
+
runner user and set python-version to a version already cached there, bypassing
|
|
50
|
+
the framework installer entirely.
|
|
51
|
+
fix_code:
|
|
52
|
+
- language: yaml
|
|
53
|
+
label: 'Workaround: use pre-installed Python to avoid the installer'
|
|
54
|
+
code: |
|
|
55
|
+
jobs:
|
|
56
|
+
build:
|
|
57
|
+
runs-on: [self-hosted, macos]
|
|
58
|
+
steps:
|
|
59
|
+
# If Python 3.14 is pre-installed system-wide (via pkg installer as root),
|
|
60
|
+
# setup-python finds it in PATH without invoking setup.sh
|
|
61
|
+
- uses: actions/setup-python@v5
|
|
62
|
+
with:
|
|
63
|
+
python-version: '3.14'
|
|
64
|
+
- run: python3 --version
|
|
65
|
+
- language: yaml
|
|
66
|
+
label: 'Workaround: grant passwordless sudo to runner user via /etc/sudoers (NOT recommended for production)'
|
|
67
|
+
code: |
|
|
68
|
+
# Add to /etc/sudoers on the macOS runner machine (use visudo):
|
|
69
|
+
# runner-user ALL=(ALL) NOPASSWD: ALL
|
|
70
|
+
#
|
|
71
|
+
# This allows setup-python's installer to use sudo for both the framework
|
|
72
|
+
# install and symlink creation steps.
|
|
73
|
+
#
|
|
74
|
+
# In your workflow, no changes are needed — setup-python works normally once
|
|
75
|
+
# the runner user has the required sudo permissions.
|
|
76
|
+
jobs:
|
|
77
|
+
build:
|
|
78
|
+
runs-on: [self-hosted, macos]
|
|
79
|
+
steps:
|
|
80
|
+
- uses: actions/setup-python@v5
|
|
81
|
+
with:
|
|
82
|
+
python-version: '3.14'
|
|
83
|
+
prevention:
|
|
84
|
+
- 'Use pre-installed Python on macOS self-hosted runners to avoid the setup.sh installer and its sudo/symlink requirements'
|
|
85
|
+
- 'When provisioning macOS self-hosted runners, ensure the runner user has passwordless sudo or pre-install all required Python versions'
|
|
86
|
+
- 'Track actions/python-versions#384 for an upstream fix that adds sudo to the symlink creation step'
|
|
87
|
+
- 'Test setup-python on macOS self-hosted runners in a staging environment before deploying to production'
|
|
88
|
+
docs:
|
|
89
|
+
- url: 'https://github.com/actions/setup-python/issues/1301'
|
|
90
|
+
label: 'actions/setup-python#1301: Permission denied when creating symlinks on macOS self-hosted runners (2026)'
|
|
91
|
+
- url: 'https://github.com/actions/python-versions/pull/384'
|
|
92
|
+
label: 'actions/python-versions PR #384: fix symlink creation to use sudo (pending)'
|
|
93
|
+
- url: 'https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners#self-hosted-runner-security'
|
|
94
|
+
label: 'GitHub Docs: Self-hosted runner security'
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
id: runner-environment-197
|
|
2
|
+
title: 'setup-python fails on Windows self-hosted runner without administrator permissions — InstallAllUsers=1 MSI installer requires admin'
|
|
3
|
+
category: runner-environment
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- setup-python
|
|
7
|
+
- self-hosted
|
|
8
|
+
- windows
|
|
9
|
+
- admin-permissions
|
|
10
|
+
- msi-installer
|
|
11
|
+
patterns:
|
|
12
|
+
- regex: 'Error happened during Python installation'
|
|
13
|
+
flags: 'i'
|
|
14
|
+
- regex: 'InstallAllUsers=1'
|
|
15
|
+
flags: 'i'
|
|
16
|
+
- regex: 'setup-python.*self.hosted.*windows.*fail'
|
|
17
|
+
flags: 'i'
|
|
18
|
+
error_messages:
|
|
19
|
+
- 'Error happened during Python installation'
|
|
20
|
+
root_cause: |
|
|
21
|
+
The setup-python action installs Python using the official MSI installer with the
|
|
22
|
+
flag InstallAllUsers=1. This flag installs Python into the shared runner tool cache
|
|
23
|
+
(RUNNER_TOOL_CACHE) using the DefaultAllUsersTargetDir argument, which requires
|
|
24
|
+
administrator privileges to write to the shared system-level installation path.
|
|
25
|
+
|
|
26
|
+
When the GitHub Actions runner service is running under a standard user account
|
|
27
|
+
without local administrator permissions, the Python MSI installer fails because it
|
|
28
|
+
cannot write to the required system paths, resulting in:
|
|
29
|
+
|
|
30
|
+
Error happened during Python installation
|
|
31
|
+
|
|
32
|
+
This affects Windows self-hosted runners configured as a Windows service under a
|
|
33
|
+
non-admin account. GitHub-hosted Windows runners are unaffected because they run
|
|
34
|
+
as SYSTEM (full admin). Linux and macOS self-hosted runners are unaffected.
|
|
35
|
+
|
|
36
|
+
Note: this is by design per the action maintainers — InstallAllUsers=1 is required
|
|
37
|
+
to correctly populate the shared RUNNER_TOOL_CACHE. A per-user install mode
|
|
38
|
+
(InstallAllUsers=0) is under consideration as a future enhancement.
|
|
39
|
+
fix: |
|
|
40
|
+
Primary fix: Configure the Windows runner service to run as a local administrator
|
|
41
|
+
account. In Windows Services (services.msc), change the "Log On" account for the
|
|
42
|
+
GitHub Actions Runner service to an account with local admin rights, or install the
|
|
43
|
+
runner using the .\config.cmd --runasservice flow with an admin account.
|
|
44
|
+
|
|
45
|
+
Workaround 1: Pre-install the required Python version system-wide on the runner
|
|
46
|
+
machine before workflows run. setup-python will use the pre-installed version from
|
|
47
|
+
PATH without invoking the MSI installer if the version matches.
|
|
48
|
+
|
|
49
|
+
Workaround 2: Ensure the runner is run interactively (not as a service) under an
|
|
50
|
+
account with admin rights during initial Python installation, then cache the tool.
|
|
51
|
+
|
|
52
|
+
Workaround 3: Use actions/setup-python''s uses: together with a self-hosted runner
|
|
53
|
+
image that already has Python pre-installed in RUNNER_TOOL_CACHE, bypassing the
|
|
54
|
+
MSI install step entirely.
|
|
55
|
+
fix_code:
|
|
56
|
+
- language: yaml
|
|
57
|
+
label: 'Workflow: no changes needed — fix is on the runner machine configuration'
|
|
58
|
+
code: |
|
|
59
|
+
# Fix requires reconfiguring the Windows runner service account:
|
|
60
|
+
# 1. Open Services (services.msc) on the runner machine
|
|
61
|
+
# 2. Find "GitHub Actions Runner (<name>)"
|
|
62
|
+
# 3. Right-click → Properties → Log On tab
|
|
63
|
+
# 4. Change to an account with local administrator privileges
|
|
64
|
+
# 5. Restart the service
|
|
65
|
+
#
|
|
66
|
+
# After reconfiguring, setup-python works normally:
|
|
67
|
+
jobs:
|
|
68
|
+
build:
|
|
69
|
+
runs-on: [self-hosted, windows]
|
|
70
|
+
steps:
|
|
71
|
+
- uses: actions/setup-python@v5
|
|
72
|
+
with:
|
|
73
|
+
python-version: '3.12'
|
|
74
|
+
- run: python --version
|
|
75
|
+
- language: yaml
|
|
76
|
+
label: 'Workaround: use pre-installed Python from PATH if runner has it installed system-wide'
|
|
77
|
+
code: |
|
|
78
|
+
jobs:
|
|
79
|
+
build:
|
|
80
|
+
runs-on: [self-hosted, windows]
|
|
81
|
+
steps:
|
|
82
|
+
# Skip setup-python entirely if Python is pre-installed system-wide
|
|
83
|
+
- name: Verify Python available
|
|
84
|
+
run: python --version
|
|
85
|
+
# OR use setup-python only to add to PATH, not install:
|
|
86
|
+
- uses: actions/setup-python@v5
|
|
87
|
+
with:
|
|
88
|
+
python-version: '3.12'
|
|
89
|
+
# If Python 3.12 is already in RUNNER_TOOL_CACHE, no install occurs
|
|
90
|
+
prevention:
|
|
91
|
+
- 'Always run Windows self-hosted runner services under a local administrator account — setup-python requires admin rights to install into the shared tool cache'
|
|
92
|
+
- 'Test setup-python on self-hosted runners with the same service account before deploying to production workloads'
|
|
93
|
+
- 'Use pre-installed Python on Windows self-hosted runners to avoid the MSI installer entirely when admin rights cannot be granted'
|
|
94
|
+
- 'Document the runner service account requirements in your team''s self-hosted runner setup guide'
|
|
95
|
+
docs:
|
|
96
|
+
- url: 'https://github.com/actions/setup-python/issues/1308'
|
|
97
|
+
label: 'actions/setup-python#1308: fails on self-hosted runners without admin permissions (2026)'
|
|
98
|
+
- url: 'https://github.com/actions/setup-python/blob/main/docs/advanced-usage.md#windows'
|
|
99
|
+
label: 'setup-python docs: Windows advanced usage and self-hosted runner configuration'
|
|
100
|
+
- url: 'https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/configuring-the-self-hosted-runner-application-as-a-service'
|
|
101
|
+
label: 'GitHub Docs: Configuring the self-hosted runner as a service'
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
id: silent-failures-105
|
|
2
|
+
title: 'checkout@v6 clean: false still deletes workspace when remote URL changes between checkouts'
|
|
3
|
+
category: silent-failures
|
|
4
|
+
severity: silent-failure
|
|
5
|
+
tags:
|
|
6
|
+
- checkout
|
|
7
|
+
- clean
|
|
8
|
+
- workspace
|
|
9
|
+
- multi-checkout
|
|
10
|
+
- v6
|
|
11
|
+
- remote-url
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: 'Deleting the contents of.*work.*\n.*Initializing the repository'
|
|
14
|
+
flags: 'i'
|
|
15
|
+
- regex: 'clean:\s*false[\s\S]{0,500}Deleting the contents of'
|
|
16
|
+
flags: 'i'
|
|
17
|
+
- regex: 'git config --local --get remote\.origin\.url[\s\S]{0,200}Deleting the contents'
|
|
18
|
+
flags: 'i'
|
|
19
|
+
error_messages:
|
|
20
|
+
- 'Deleting the contents of ''/home/runner/work/myrepo/myrepo'''
|
|
21
|
+
- 'Deleting the contents of ''/home/runner/work/_temp/...'
|
|
22
|
+
root_cause: |
|
|
23
|
+
actions/checkout's `clean: false` option prevents `git clean -ffdx` (removing untracked
|
|
24
|
+
files) but does NOT prevent the action from deleting and reinitializing the entire
|
|
25
|
+
workspace directory when it detects that the existing `remote.origin.url` does not match
|
|
26
|
+
the target repository being checked out.
|
|
27
|
+
|
|
28
|
+
When multiple checkout steps run in the same job and the second checkout targets a
|
|
29
|
+
different repository (different org, different repo name, or different URL), the action
|
|
30
|
+
reads the current `git config --local --get remote.origin.url`, compares it against the
|
|
31
|
+
target repository URL, and — on mismatch — deletes the entire workspace directory before
|
|
32
|
+
reinitializing. This deletion happens regardless of `clean: false`.
|
|
33
|
+
|
|
34
|
+
Common scenarios that trigger this:
|
|
35
|
+
1. First step checks out a support/config repo (sparse-checkout of a different repo for
|
|
36
|
+
shared config), then a second step checks out the main repo with `clean: false`.
|
|
37
|
+
2. Checking out the main repo first, then a second checkout of a different repo for
|
|
38
|
+
reading shared scripts, assuming `clean: false` preserves the main workspace.
|
|
39
|
+
3. Re-using runner workspace across jobs via `clean: false` where the prior job checked
|
|
40
|
+
out a different repository.
|
|
41
|
+
|
|
42
|
+
The log shows the silent deletion in plain text ("Deleting the contents of '...'") but
|
|
43
|
+
users commonly miss it because the step still succeeds and subsequent steps may not
|
|
44
|
+
immediately error if they only use the freshly-checked-out content.
|
|
45
|
+
|
|
46
|
+
checkout@v5 has the same behavior — this is not a v6 regression. It is documented as
|
|
47
|
+
expected behavior but is frequently unexpected by users.
|
|
48
|
+
fix: |
|
|
49
|
+
Option 1 (recommended): Specify `path:` to checkout each repository into a distinct
|
|
50
|
+
subdirectory, preventing the remote URL mismatch from triggering deletion.
|
|
51
|
+
|
|
52
|
+
Option 2: Reverse the order — checkout the main repo last so the deletion (if any)
|
|
53
|
+
happens to the support repo's files rather than the main workspace.
|
|
54
|
+
|
|
55
|
+
Option 3: Accept that `clean: false` cannot preserve workspace contents across
|
|
56
|
+
checkouts of different repositories sharing the same path, and restructure the workflow
|
|
57
|
+
to avoid this pattern.
|
|
58
|
+
|
|
59
|
+
Option 4: For reading shared scripts/config from another repo, use curl/gh api to fetch
|
|
60
|
+
specific files rather than a full checkout step.
|
|
61
|
+
fix_code:
|
|
62
|
+
- language: yaml
|
|
63
|
+
label: 'Use path: to isolate each checkout to its own directory'
|
|
64
|
+
code: |
|
|
65
|
+
jobs:
|
|
66
|
+
build:
|
|
67
|
+
runs-on: ubuntu-latest
|
|
68
|
+
steps:
|
|
69
|
+
# Checkout support config into a subdirectory
|
|
70
|
+
- name: Checkout shared config
|
|
71
|
+
uses: actions/checkout@v6
|
|
72
|
+
with:
|
|
73
|
+
repository: myorg/shared-config
|
|
74
|
+
ref: v1
|
|
75
|
+
sparse-checkout: |
|
|
76
|
+
nginx/nginx.conf
|
|
77
|
+
path: .shared-config # <-- isolated path, no URL conflict
|
|
78
|
+
|
|
79
|
+
# Checkout main repo into workspace root (or another path)
|
|
80
|
+
- name: Checkout source
|
|
81
|
+
uses: actions/checkout@v6
|
|
82
|
+
with:
|
|
83
|
+
fetch-depth: 0
|
|
84
|
+
# clean: false is now safe — different paths, no URL mismatch
|
|
85
|
+
|
|
86
|
+
- name: Use shared config
|
|
87
|
+
run: cp .shared-config/nginx/nginx.conf ./nginx.conf
|
|
88
|
+
|
|
89
|
+
- language: yaml
|
|
90
|
+
label: 'Fetch individual files without a full checkout to avoid URL conflict'
|
|
91
|
+
code: |
|
|
92
|
+
jobs:
|
|
93
|
+
build:
|
|
94
|
+
runs-on: ubuntu-latest
|
|
95
|
+
steps:
|
|
96
|
+
- uses: actions/checkout@v6
|
|
97
|
+
with:
|
|
98
|
+
fetch-depth: 0
|
|
99
|
+
|
|
100
|
+
# Fetch a single file from another repo without a second checkout
|
|
101
|
+
- name: Fetch shared nginx config
|
|
102
|
+
env:
|
|
103
|
+
GH_TOKEN: ${{ github.token }}
|
|
104
|
+
run: |
|
|
105
|
+
gh api repos/myorg/shared-config/contents/nginx/nginx.conf \
|
|
106
|
+
--jq '.content' | base64 -d > ./nginx.conf
|
|
107
|
+
|
|
108
|
+
prevention:
|
|
109
|
+
- 'Use path: on every checkout step when multiple repositories are checked out in the same job'
|
|
110
|
+
- 'Do not rely on clean: false to preserve workspace content across checkouts of different repositories'
|
|
111
|
+
- 'Watch for "Deleting the contents of..." lines in checkout step logs — this confirms workspace was reset even with clean: false'
|
|
112
|
+
- 'When using sparse-checkout for a support repo followed by a main repo checkout, always isolate them into separate path: directories'
|
|
113
|
+
docs:
|
|
114
|
+
- url: 'https://github.com/actions/checkout/issues/2348'
|
|
115
|
+
label: 'actions/checkout#2348 — v6 clean: false still deletes workspace files from prior checkout (Feb 2026)'
|
|
116
|
+
- url: 'https://github.com/actions/checkout#usage'
|
|
117
|
+
label: 'actions/checkout — clean input documentation'
|
|
118
|
+
- url: 'https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/storing-workflow-data-as-artifacts'
|
|
119
|
+
label: 'Storing workflow data — alternative to multi-repo checkout for sharing files'
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
id: silent-failures-103
|
|
2
|
+
title: "concurrency queue: max silently ignored when cancel-in-progress: true is also set"
|
|
3
|
+
category: silent-failures
|
|
4
|
+
severity: silent-failure
|
|
5
|
+
tags:
|
|
6
|
+
- concurrency
|
|
7
|
+
- queue
|
|
8
|
+
- cancel-in-progress
|
|
9
|
+
- silent-failure
|
|
10
|
+
- deployment
|
|
11
|
+
- serialization
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: 'This run has been cancelled'
|
|
14
|
+
flags: 'i'
|
|
15
|
+
- regex: 'Canceling since a higher priority waiting run was found'
|
|
16
|
+
flags: 'i'
|
|
17
|
+
- regex: 'queue:\s*max'
|
|
18
|
+
flags: 'i'
|
|
19
|
+
error_messages:
|
|
20
|
+
- "This run has been cancelled."
|
|
21
|
+
- "Canceling since a higher priority waiting run was found"
|
|
22
|
+
root_cause: |
|
|
23
|
+
GitHub Actions introduced `queue: max` in May 2026 as a way to allow up to 100
|
|
24
|
+
pending runs to wait in a concurrency group instead of being cancelled and
|
|
25
|
+
replaced. Adding `queue: max` to an existing concurrency block without removing
|
|
26
|
+
`cancel-in-progress: true` results in the `queue: max` setting being silently
|
|
27
|
+
ignored — no validation error is raised, no warning is emitted.
|
|
28
|
+
|
|
29
|
+
The concurrency group continues to cancel pending runs exactly as it did before.
|
|
30
|
+
The developer believes their deployment queue is now buffering up to 100 runs,
|
|
31
|
+
but every third commit or concurrent PR merge still cancels the previously queued
|
|
32
|
+
run, dropping deployments silently.
|
|
33
|
+
|
|
34
|
+
The language services editor plugin (VS Code Actions extension) does report a
|
|
35
|
+
lint error for this combination, but:
|
|
36
|
+
- Not all teams have the extension installed or enabled.
|
|
37
|
+
- The Actions UI and `gh` CLI do not surface the conflict at run time.
|
|
38
|
+
- The workflow file passes schema validation and runs without a reported error.
|
|
39
|
+
|
|
40
|
+
The practical symptom is identical to having no `queue: max` at all: runs are
|
|
41
|
+
still cancelled, the queue never grows beyond one pending run, and deployments
|
|
42
|
+
are dropped during high-frequency push periods — exactly the problem `queue: max`
|
|
43
|
+
was supposed to solve.
|
|
44
|
+
fix: |
|
|
45
|
+
Remove `cancel-in-progress: true` (or omit it entirely, since `false` is the
|
|
46
|
+
default) when using `queue: max`. These two options are mutually exclusive:
|
|
47
|
+
|
|
48
|
+
- `cancel-in-progress: true` — cancel the pending run when a newer run arrives.
|
|
49
|
+
- `queue: max` — hold up to 100 pending runs in order.
|
|
50
|
+
|
|
51
|
+
If you need both semantics (cancel old pending runs for feature branches but queue
|
|
52
|
+
for main), split into separate concurrency group expressions per ref:
|
|
53
|
+
|
|
54
|
+
```yaml
|
|
55
|
+
concurrency:
|
|
56
|
+
group: deploy-${{ github.ref }}
|
|
57
|
+
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
|
|
58
|
+
# Do NOT add queue: max when cancel-in-progress may be true
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
For the main branch where ordered deploys matter, use `queue: max` alone:
|
|
62
|
+
|
|
63
|
+
```yaml
|
|
64
|
+
concurrency:
|
|
65
|
+
group: deploy-production
|
|
66
|
+
queue: max
|
|
67
|
+
# cancel-in-progress must be omitted or set to false
|
|
68
|
+
```
|
|
69
|
+
fix_code:
|
|
70
|
+
- language: yaml
|
|
71
|
+
label: "WRONG — queue: max silently ignored when cancel-in-progress: true"
|
|
72
|
+
code: |
|
|
73
|
+
concurrency:
|
|
74
|
+
group: deploy-${{ github.repository }}-${{ github.ref }}
|
|
75
|
+
cancel-in-progress: true # ← PROBLEM: negates queue: max
|
|
76
|
+
queue: max # ← silently ignored, no error shown
|
|
77
|
+
- language: yaml
|
|
78
|
+
label: "CORRECT — use queue: max without cancel-in-progress"
|
|
79
|
+
code: |
|
|
80
|
+
concurrency:
|
|
81
|
+
group: deploy-${{ github.repository }}-${{ github.ref }}
|
|
82
|
+
queue: max # ← up to 100 pending runs queued
|
|
83
|
+
# cancel-in-progress is false by default — omit it entirely
|
|
84
|
+
- language: yaml
|
|
85
|
+
label: "ADVANCED — cancel-in-progress for branches, queue for main"
|
|
86
|
+
code: |
|
|
87
|
+
concurrency:
|
|
88
|
+
group: deploy-${{ github.repository }}-${{ github.ref }}
|
|
89
|
+
# Dynamic cancel: cancel feature branch runs (fast feedback), queue
|
|
90
|
+
# main branch deploys (preserve ordering).
|
|
91
|
+
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
|
|
92
|
+
# Note: queue: max cannot be combined with cancel-in-progress.
|
|
93
|
+
# For main branch serialization without cancel, omit cancel-in-progress
|
|
94
|
+
# and rely on queue: max in a separate workflow targeting only main.
|
|
95
|
+
prevention:
|
|
96
|
+
- "When adding `queue: max` to an existing concurrency block, always audit the
|
|
97
|
+
block for a `cancel-in-progress: true` setting and remove it."
|
|
98
|
+
- "Install the GitHub Actions VS Code extension — it reports a lint error for
|
|
99
|
+
`queue: max` + `cancel-in-progress: true` combinations before you push."
|
|
100
|
+
- "After enabling `queue: max`, verify it works by triggering two rapid pushes
|
|
101
|
+
and confirming both runs appear in the Actions UI as 'Queued' rather than one
|
|
102
|
+
being cancelled."
|
|
103
|
+
docs:
|
|
104
|
+
- url: "https://github.blog/changelog/2026-05-07-github-actions-concurrency-groups-now-allow-larger-queues/"
|
|
105
|
+
label: "GitHub Changelog: GitHub Actions concurrency groups now allow larger queues (May 7, 2026)"
|
|
106
|
+
- url: "https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/using-concurrency"
|
|
107
|
+
label: "Using concurrency — GitHub Actions documentation"
|
|
108
|
+
- url: "https://github.com/actions/languageservices/pull/355"
|
|
109
|
+
label: "actions/languageservices#355: Add queue property to concurrency, validate queue+cancel-in-progress conflict"
|