@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.
Files changed (34) hide show
  1. package/errors/caching-artifacts/cache-corrupt-on-cancel-during-restore-save-always.yml +136 -0
  2. package/errors/caching-artifacts/restore-keys-asterisk-literal-not-glob.yml +107 -0
  3. package/errors/concurrency-timing/concurrency-timing-053.yml +83 -0
  4. package/errors/concurrency-timing/pull-request-review-shared-concurrency-cancels-ci.yml +131 -0
  5. package/errors/known-unsolved/github-script-esm-not-supported.yml +111 -0
  6. package/errors/known-unsolved/job-outputs-string-only-no-array-object.yml +142 -0
  7. package/errors/known-unsolved/known-unsolved-062.yml +87 -0
  8. package/errors/known-unsolved/runner-rest-api-busy-false-broker-state-desync.yml +102 -0
  9. package/errors/permissions-auth/oidc-immutable-sub-claim-new-repo-trust-policy-mismatch.yml +122 -0
  10. package/errors/permissions-auth/permissions-auth-064.yml +122 -0
  11. package/errors/permissions-auth/permissions-auth-065.yml +97 -0
  12. package/errors/permissions-auth/permissions-auth-066.yml +129 -0
  13. package/errors/permissions-auth/upload-code-coverage-missing-code-quality-write-permission.yml +94 -0
  14. package/errors/runner-environment/arc-kubernetes-checkout-circular-json-container-hook.yml +101 -0
  15. package/errors/runner-environment/cache-restore-windows-runner-silent-crash.yml +130 -0
  16. package/errors/runner-environment/git-248-fetch-tags-shallow-clone-regression.yml +100 -0
  17. package/errors/runner-environment/javascript-actions-alpine-arm64-not-supported.yml +121 -0
  18. package/errors/runner-environment/runner-environment-188.yml +96 -0
  19. package/errors/runner-environment/runner-environment-191.yml +147 -0
  20. package/errors/runner-environment/runner-environment-192.yml +144 -0
  21. package/errors/runner-environment/runner-environment-193.yml +136 -0
  22. package/errors/runner-environment/runner-environment-194.yml +86 -0
  23. package/errors/runner-environment/runner-environment-199.yml +93 -0
  24. package/errors/runner-environment/setup-python-macos-self-hosted-symlink-permission-denied.yml +94 -0
  25. package/errors/runner-environment/setup-python-windows-self-hosted-no-admin-install-fails.yml +101 -0
  26. package/errors/silent-failures/checkout-v6-clean-false-deletes-workspace-on-repo-change.yml +119 -0
  27. package/errors/silent-failures/queue-max-silently-ignored-with-cancel-in-progress.yml +109 -0
  28. package/errors/silent-failures/silent-failures-102.yml +141 -0
  29. package/errors/silent-failures/silent-failures-104.yml +119 -0
  30. package/errors/triggers/triggers-069.yml +100 -0
  31. package/errors/yaml-syntax/continue-on-error-inputs-composite-action-unexpected-value.yml +110 -0
  32. package/errors/yaml-syntax/yaml-syntax-068.yml +137 -0
  33. package/errors/yaml-syntax/yaml-syntax-069.yml +118 -0
  34. 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'
@@ -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"