@htekdev/actions-debugger 1.0.97 → 1.0.98

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.
@@ -0,0 +1,112 @@
1
+ id: known-unsolved-054
2
+ title: 'github.event in a reusable workflow is the workflow_call event, not the caller event'
3
+ category: known-unsolved
4
+ severity: silent-failure
5
+ tags:
6
+ - reusable-workflow
7
+ - workflow-call
8
+ - github-event
9
+ - context
10
+ - inputs
11
+ - github-context
12
+ patterns:
13
+ - regex: 'github\.event\.(pull_request|commits|release|head_commit)\b'
14
+ flags: 'i'
15
+ error_messages: []
16
+ root_cause: |
17
+ When a caller workflow invokes a reusable workflow via jobs.<id>.uses, the
18
+ github.event context inside the callee is the workflow_call event object,
19
+ NOT the triggering event (push, pull_request, schedule, etc.) of the caller.
20
+
21
+ All event-specific payload fields are undefined inside the reusable workflow
22
+ and evaluate to empty string or null without any error:
23
+ - github.event.pull_request (undefined — returns null)
24
+ - github.event.commits (undefined — returns null)
25
+ - github.event.release (undefined — returns null)
26
+ - github.event.head_commit (undefined — returns null)
27
+ - github.event.inputs (undefined — use inputs context instead)
28
+
29
+ Additionally, github.event_name inside the callee always returns 'workflow_call',
30
+ regardless of what event triggered the caller.
31
+
32
+ Importantly, github.ref, github.sha, and github.actor DO retain the caller's
33
+ values inside the callee — it is specifically github.event and github.event_name
34
+ that reflect the workflow_call context, not the caller's triggering event.
35
+
36
+ This catches developers by surprise when refactoring inline jobs into reusable
37
+ workflows: the refactored callee silently loses access to the event payload it
38
+ previously used, with no validation error or warning at parse time or runtime.
39
+
40
+ This is by design — reusable workflows execute as independent workflow_call
41
+ events and there is no mechanism to inherit the caller's event context. GitHub
42
+ has confirmed this will not change.
43
+ fix: |
44
+ There is no workaround that exposes the caller's github.event inside the callee.
45
+ The required approach is to declare all needed event data as explicit inputs:
46
+ in the reusable workflow and forward them via with: in the caller.
47
+
48
+ github.ref, github.sha, and github.actor are available in the callee without
49
+ any explicit forwarding — they are inherited automatically from the caller context.
50
+ fix_code:
51
+ - language: yaml
52
+ label: 'Wrong — accessing caller event payload inside reusable workflow (silently empty)'
53
+ code: |
54
+ # .github/workflows/reusable.yml — these are all EMPTY inside the callee
55
+ on:
56
+ workflow_call:
57
+
58
+ jobs:
59
+ process:
60
+ runs-on: ubuntu-latest
61
+ steps:
62
+ - run: echo "PR = ${{ github.event.pull_request.number }}" # null
63
+ - run: echo "Event = ${{ github.event_name }}" # 'workflow_call'
64
+ - run: echo "Commit = ${{ github.event.head_commit.message }}" # null
65
+ - language: yaml
66
+ label: 'Correct — declare inputs in callee and forward event data from caller'
67
+ code: |
68
+ # .github/workflows/reusable.yml — declare needed event data as inputs
69
+ on:
70
+ workflow_call:
71
+ inputs:
72
+ pr_number:
73
+ type: number
74
+ default: 0
75
+ description: 'Pull request number from github.event.pull_request.number'
76
+ triggering_event:
77
+ type: string
78
+ required: true
79
+ description: 'The caller event name (github.event_name)'
80
+
81
+ jobs:
82
+ process:
83
+ runs-on: ubuntu-latest
84
+ steps:
85
+ - run: echo "PR = ${{ inputs.pr_number }}"
86
+ - run: echo "Triggered by = ${{ inputs.triggering_event }}"
87
+ # github.ref and github.sha are safe to use directly — they are inherited
88
+ - run: echo "SHA = ${{ github.sha }}"
89
+
90
+ # ---- CALLER WORKFLOW ----
91
+ # .github/workflows/caller.yml — forward event data via with:
92
+ on: [push, pull_request]
93
+
94
+ jobs:
95
+ call-reusable:
96
+ uses: ./.github/workflows/reusable.yml
97
+ with:
98
+ pr_number: ${{ github.event.pull_request.number || 0 }}
99
+ triggering_event: ${{ github.event_name }}
100
+ prevention:
101
+ - 'Never access github.event.* fields directly inside a reusable workflow — they will always be empty'
102
+ - 'github.event_name inside a reusable workflow always returns workflow_call, not the caller event'
103
+ - 'Declare all required event data as explicit workflow_call inputs and forward with with: in the caller'
104
+ - 'github.ref, github.sha, and github.actor are inherited from the caller and are safe to use'
105
+ - 'Add a comment in the reusable workflow reminding contributors not to use github.event directly'
106
+ docs:
107
+ - url: 'https://docs.github.com/en/actions/sharing-automations/reusing-workflows#limitations'
108
+ label: 'GitHub Docs — Reusing workflows: Limitations'
109
+ - url: 'https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/contexts#github-context'
110
+ label: 'GitHub Docs — github context'
111
+ - url: 'https://docs.github.com/en/actions/sharing-automations/reusing-workflows#passing-inputs-and-secrets-to-a-called-workflow'
112
+ label: 'GitHub Docs — Passing inputs and secrets to a called workflow'
@@ -0,0 +1,114 @@
1
+ id: permissions-auth-056
2
+ title: 'OIDC token requests rate-limited in large parallel matrix — random 429 job failures'
3
+ category: permissions-auth
4
+ severity: error
5
+ tags:
6
+ - oidc
7
+ - id-token
8
+ - rate-limit
9
+ - matrix
10
+ - parallel
11
+ - aws
12
+ - gcp
13
+ - azure
14
+ patterns:
15
+ - regex: 'Failed to get ID token.*429'
16
+ flags: 'i'
17
+ - regex: 'ACTIONS_ID_TOKEN_REQUEST_URL.*429'
18
+ flags: 'i'
19
+ - regex: 'No ID token is available.*rate.limit'
20
+ flags: 'i'
21
+ error_messages:
22
+ - "Error: Failed to get ID token: Request failed with status code 429"
23
+ - "Error: Failed to get ID token: Error code: 429"
24
+ root_cause: |
25
+ GitHub's OIDC token endpoint (ACTIONS_ID_TOKEN_REQUEST_URL) has per-workflow-run
26
+ rate limits on simultaneous token requests. When a large matrix workflow spawns
27
+ many parallel jobs (typically 20+) that all request OIDC tokens at the start of
28
+ their runs, the burst of simultaneous requests can exceed the endpoint's rate
29
+ limit, and some jobs receive HTTP 429 responses.
30
+
31
+ Cloud provider actions that call the OIDC endpoint internally during setup
32
+ are affected:
33
+ - aws-actions/configure-aws-credentials
34
+ - google-github-actions/auth
35
+ - azure/login (with OIDC federated credentials)
36
+
37
+ In a large matrix, all legs start within seconds of each other, creating a
38
+ simultaneous burst that exceeds the endpoint limit. The failure is
39
+ non-deterministic: some jobs succeed and some fail on any given run. Manually
40
+ re-running the failed jobs typically succeeds because the burst window has
41
+ passed. This intermittent behavior makes the 429 root cause difficult to
42
+ diagnose without inspecting verbose action output for the HTTP status code.
43
+
44
+ The rate limit is enforced per workflow run, not per repository or per user.
45
+ Actions that include built-in retry logic may mask the error by successfully
46
+ retrying, but add latency to affected jobs.
47
+ fix: |
48
+ Reduce parallel OIDC token requests by setting max-parallel on the matrix
49
+ strategy. A value between 5 and 15 typically prevents rate limit breaches
50
+ while still providing meaningful parallelism.
51
+
52
+ Alternatively, restructure the workflow to acquire a single OIDC-derived
53
+ credential in a setup job and pass it as a job output to downstream matrix
54
+ jobs — but this must be done carefully to avoid exposing short-lived tokens
55
+ in workflow logs. Check the cloud provider's documentation for recommended
56
+ token-sharing patterns.
57
+
58
+ Enable step debug logging (ACTIONS_STEP_DEBUG secret set to 'true') to
59
+ confirm the 429 root cause when diagnosing intermittent OIDC failures.
60
+ fix_code:
61
+ - language: yaml
62
+ label: 'Set max-parallel to prevent simultaneous OIDC token request burst'
63
+ code: |
64
+ jobs:
65
+ deploy:
66
+ strategy:
67
+ matrix:
68
+ region: [us-east-1, us-west-2, eu-west-1, ap-southeast-1, ap-northeast-1,
69
+ sa-east-1, ca-central-1, ap-south-1, ap-east-1, eu-central-1]
70
+ max-parallel: 5 # Prevents simultaneous OIDC token burst
71
+ runs-on: ubuntu-latest
72
+ permissions:
73
+ id-token: write
74
+ contents: read
75
+ steps:
76
+ - name: Configure AWS credentials
77
+ uses: aws-actions/configure-aws-credentials@v4
78
+ with:
79
+ role-to-assume: arn:aws:iam::123456789:role/deploy-${{ matrix.region }}
80
+ aws-region: ${{ matrix.region }}
81
+ - name: Deploy
82
+ run: ./scripts/deploy.sh ${{ matrix.region }}
83
+ - language: yaml
84
+ label: 'Enable OIDC debug logging to confirm 429 rate limit as root cause'
85
+ code: |
86
+ # Add this secret to the repository: ACTIONS_STEP_DEBUG = true
87
+ # Then re-run the failing workflow and check step logs for:
88
+ # "Request failed with status code 429"
89
+ # in the cloud auth action's output to confirm rate limiting.
90
+
91
+ jobs:
92
+ deploy:
93
+ runs-on: ubuntu-latest
94
+ permissions:
95
+ id-token: write
96
+ steps:
97
+ - name: Configure credentials (verbose for debugging)
98
+ uses: aws-actions/configure-aws-credentials@v4
99
+ with:
100
+ role-to-assume: arn:aws:iam::123456789:role/ci-role
101
+ aws-region: us-east-1
102
+ prevention:
103
+ - 'Use max-parallel on matrix strategies that use OIDC authentication to limit burst requests'
104
+ - 'Enable ACTIONS_STEP_DEBUG secret to see HTTP status codes in cloud auth action logs'
105
+ - 'Treat intermittent OIDC failures in large matrix workflows as a 429 rate limit until proven otherwise'
106
+ - 'Check whether the cloud auth action has built-in retry logic — some versions retry automatically'
107
+ - 'Consider staggering matrix jobs with a sleep step if max-parallel alone does not resolve the issue'
108
+ docs:
109
+ - url: 'https://docs.github.com/en/actions/security-for-github-actions/security-hardening-your-deployments/about-security-hardening-with-openid-connect'
110
+ label: 'GitHub Docs — About security hardening with OpenID Connect'
111
+ - url: 'https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idstrategymax-parallel'
112
+ label: 'GitHub Docs — jobs.<job_id>.strategy.max-parallel'
113
+ - url: 'https://docs.github.com/en/actions/monitoring-and-troubleshooting-workflows/enabling-debug-logging'
114
+ label: 'GitHub Docs — Enabling debug logging'
@@ -0,0 +1,97 @@
1
+ id: silent-failures-088
2
+ title: 'vars.* context: environment-scoped variable silently shadows repository and org variable'
3
+ category: silent-failures
4
+ severity: silent-failure
5
+ tags:
6
+ - vars
7
+ - variables
8
+ - environment
9
+ - precedence
10
+ - shadow
11
+ - configuration
12
+ patterns:
13
+ - regex: 'vars\.[A-Z_]+'
14
+ flags: 'i'
15
+ error_messages: []
16
+ root_cause: |
17
+ The vars.* context resolves configuration variables in strict precedence order:
18
+ environment-scoped > repository-level > organization-level. When a job specifies
19
+ an environment: key, any variable defined at that deployment environment's scope
20
+ with the same name as a repository or organization variable silently overrides
21
+ the higher-scope value.
22
+
23
+ No warning or error is emitted when shadowing occurs. The workflow runs
24
+ successfully but uses the environment-scoped value rather than the expected
25
+ org or repository value.
26
+
27
+ Common scenario: an organization defines vars.REGION='us-east-1' for all repos.
28
+ A production deployment environment defines vars.REGION='eu-west-1' to override
29
+ it for EU deploys. All jobs that reference the production environment now receive
30
+ 'eu-west-1' — including notification jobs, post-deploy validation jobs, or any
31
+ other job that happens to run in the production environment but was not intended
32
+ to use the EU override.
33
+
34
+ Unlike secrets, where absence raises a validation error, variable shadowing is
35
+ entirely transparent to the workflow author. Debugging requires manually
36
+ inspecting variable scopes in GitHub Settings across three levels (org, repo,
37
+ environment) to find the effective value.
38
+ fix: |
39
+ Use scope-specific prefixes for variables that intentionally override
40
+ parent-scope defaults (e.g., PROD_REGION instead of REGION). Audit effective
41
+ variable values at runtime by echoing vars.* at the start of critical jobs.
42
+
43
+ To inspect what is currently configured:
44
+ - GitHub > Organization Settings > Variables (org-level)
45
+ - Repo Settings > Secrets and variables > Variables (repo-level)
46
+ - Repo Settings > Environments > <name> > Variables (environment-level)
47
+ fix_code:
48
+ - language: yaml
49
+ label: 'Debug effective vars.* resolution in a job with environment scope'
50
+ code: |
51
+ jobs:
52
+ deploy:
53
+ environment: production
54
+ runs-on: ubuntu-latest
55
+ steps:
56
+ - name: Audit effective variable values
57
+ run: |
58
+ echo "REGION (effective): ${{ vars.REGION }}"
59
+ # If this shows 'eu-west-1' when you expected 'us-east-1',
60
+ # the 'production' environment has a REGION variable that
61
+ # silently shadows the org or repository-level value.
62
+ - language: yaml
63
+ label: 'Use environment-scoped prefixes to make overrides explicit'
64
+ code: |
65
+ # Organization variable: REGION=us-east-1
66
+ # Environment 'production' variable: PROD_REGION=eu-west-1 (distinct name)
67
+
68
+ jobs:
69
+ deploy:
70
+ environment: production
71
+ runs-on: ubuntu-latest
72
+ steps:
73
+ - name: Deploy to production
74
+ run: |
75
+ # Explicit — no ambiguity about which scope is used
76
+ deploy --region ${{ vars.PROD_REGION }}
77
+
78
+ notify:
79
+ environment: production
80
+ runs-on: ubuntu-latest
81
+ steps:
82
+ - name: Notify
83
+ run: |
84
+ # Without prefix, this would silently get 'eu-west-1' instead
85
+ # of 'us-east-1' if REGION is defined at environment scope
86
+ notify --datacenter ${{ vars.NOTIFICATION_REGION }}
87
+ prevention:
88
+ - 'Prefix environment-scoped variable names to make overrides explicit — PROD_REGION not REGION'
89
+ - 'Audit all three variable scopes before deployments: org, repo, and environment'
90
+ - 'Add a comment in the workflow file documenting which variables each environment is expected to override'
91
+ - 'For critical deployment config, avoid relying on implicit variable inheritance — reference scope-prefixed names'
92
+ - 'Run a variable audit step at the start of critical jobs to log effective vars.* values'
93
+ docs:
94
+ - url: 'https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables#precedence-for-variable-values'
95
+ label: 'GitHub Docs — Variable precedence for the vars.* context'
96
+ - url: 'https://docs.github.com/en/actions/managing-workflow-runs-and-deployments/managing-deployments/managing-environments-for-deployment'
97
+ label: 'GitHub Docs — Managing environments for deployment'
@@ -0,0 +1,93 @@
1
+ id: yaml-syntax-061
2
+ title: 'env context unavailable in job-level timeout-minutes field'
3
+ category: yaml-syntax
4
+ severity: error
5
+ tags:
6
+ - env
7
+ - timeout-minutes
8
+ - context
9
+ - context-availability
10
+ - job-level
11
+ patterns:
12
+ - regex: 'Unrecognized named-value: .env.'
13
+ flags: 'i'
14
+ - regex: 'timeout-minutes.*\$\{\{.*env\.'
15
+ flags: 'i'
16
+ error_messages:
17
+ - "The workflow is not valid. .github/workflows/<workflow>.yml (Line: X, Col: Y): Unrecognized named-value: 'env'. Located at position Z within expression: env.MY_TIMEOUT"
18
+ root_cause: |
19
+ The env context is not available in job-level timeout-minutes expressions.
20
+ GitHub Actions evaluates jobs.<job_id>.timeout-minutes before steps run and
21
+ before step-level env values are populated. The available contexts at this
22
+ position are: github, inputs, vars, needs, strategy, and matrix only.
23
+
24
+ Developers commonly try to make timeouts configurable by setting a workflow-level
25
+ env: block (e.g., env: { JOB_TIMEOUT: 60 }) and referencing it as
26
+ ${{ env.JOB_TIMEOUT }} in timeout-minutes, expecting it to work like env
27
+ references inside steps. This fails with a parse-time validation error because
28
+ the env context is not evaluated at job metadata positions.
29
+
30
+ Note: env IS available in step-level timeout-minutes
31
+ (jobs.<job_id>.steps[*].timeout-minutes) — this restriction only applies at
32
+ the job level. This asymmetry trips up developers who test in steps first
33
+ and then try to lift the same expression to job level.
34
+ fix: |
35
+ Use the vars context (repository or environment variables) instead of env for
36
+ job-level timeout-minutes. Repository variables can be set under
37
+ Settings > Secrets and variables > Variables and are available at job-evaluation
38
+ time.
39
+
40
+ If the timeout value needs to vary per workflow run, pass it as a workflow
41
+ input (inputs.*) for workflow_dispatch or workflow_call, or use matrix values
42
+ to parameterize timeouts per leg.
43
+ fix_code:
44
+ - language: yaml
45
+ label: 'Wrong — env context in job-level timeout-minutes (validation error)'
46
+ code: |
47
+ env:
48
+ JOB_TIMEOUT: 60
49
+
50
+ jobs:
51
+ build:
52
+ runs-on: ubuntu-latest
53
+ timeout-minutes: ${{ env.JOB_TIMEOUT }} # ERROR: env not available here
54
+ steps:
55
+ - run: make build
56
+ - language: yaml
57
+ label: 'Correct — use vars context for a configurable job timeout'
58
+ code: |
59
+ # Set JOB_TIMEOUT_MINUTES in repository Settings > Variables (e.g., "60")
60
+ jobs:
61
+ build:
62
+ runs-on: ubuntu-latest
63
+ timeout-minutes: ${{ fromJSON(vars.JOB_TIMEOUT_MINUTES || '60') }}
64
+ steps:
65
+ - run: make build
66
+ - language: yaml
67
+ label: 'Correct — pass timeout as workflow_dispatch input'
68
+ code: |
69
+ on:
70
+ workflow_dispatch:
71
+ inputs:
72
+ timeout:
73
+ type: number
74
+ default: 60
75
+ description: 'Job timeout in minutes'
76
+
77
+ jobs:
78
+ build:
79
+ runs-on: ubuntu-latest
80
+ timeout-minutes: ${{ inputs.timeout }}
81
+ steps:
82
+ - run: make build
83
+ prevention:
84
+ - 'Use vars.* (repository or environment variables) for static configurable timeouts at job level'
85
+ - 'Use inputs.* for runtime-configurable timeouts passed via workflow_dispatch or workflow_call'
86
+ - 'env context is only available at step level and below — not at the job metadata level'
87
+ - 'step-level timeout-minutes does support env context; only job-level timeout-minutes does not'
88
+ - 'Available contexts in job-level fields: github, inputs, vars, needs, strategy, matrix'
89
+ docs:
90
+ - url: 'https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/contexts#context-availability'
91
+ label: 'GitHub Docs — Context availability per workflow position'
92
+ - url: 'https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idtimeout-minutes'
93
+ label: 'GitHub Docs — jobs.<job_id>.timeout-minutes'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@htekdev/actions-debugger",
3
- "version": "1.0.97",
3
+ "version": "1.0.98",
4
4
  "description": "65+ real GitHub Actions errors, queryable by agents. CLI + MCP server + Copilot skills + error database.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",