@htekdev/actions-debugger 1.0.18 → 1.0.19

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,79 @@
1
+ id: permissions-auth-021
2
+ title: "create-github-app-token: A JSON web token could not be decoded (PEM key format)"
3
+ category: permissions-auth
4
+ severity: error
5
+ tags:
6
+ - github-app
7
+ - jwt
8
+ - private-key
9
+ - pem
10
+ - create-github-app-token
11
+ patterns:
12
+ - regex: "A JSON web token could not be decoded"
13
+ flags: "i"
14
+ - regex: "Failed to create token for .+\\(attempt \\d+\\): A JSON web token could not be decoded"
15
+ flags: "i"
16
+ error_messages:
17
+ - "A JSON web token could not be decoded - https://docs.github.com/rest"
18
+ - "Failed to create token for \"repo-name\" (attempt 1): A JSON web token could not be decoded"
19
+ - "RequestError [HttpError]: A JSON web token could not be decoded"
20
+ root_cause: |
21
+ The `actions/create-github-app-token` action signs a JWT using the GitHub App private key.
22
+ When the private key stored in the repository secret is malformed, every attempt to generate
23
+ a token fails with a 401 and this message. The action retries 4 times then fails the step.
24
+
25
+ Common causes:
26
+ 1. Trailing whitespace or the final newline stripped when pasting the PEM into the GitHub
27
+ Secrets UI (the textarea strips trailing whitespace on save)
28
+ 2. Windows-style CRLF line endings introduced during copy-paste from a text editor
29
+ 3. Missing PEM header (`-----BEGIN RSA PRIVATE KEY-----`) or footer line
30
+ 4. The Base64 body is correct but line breaks inside the key were removed
31
+ 5. The full `.pem` file was Base64-encoded before being stored (double-encoded)
32
+
33
+ The GitHub API returns HTTP 401 with the message "A JSON web token could not be decoded"
34
+ whenever the JWT signature cannot be verified, which always indicates a malformed key.
35
+ fix: |
36
+ Store the private key exactly as downloaded from GitHub — raw PEM format with LF line
37
+ endings, including the header and footer. Use the GitHub CLI to set the secret from the
38
+ downloaded file rather than copy-pasting it through the UI.
39
+
40
+ 1. Download the private key from the GitHub App settings page
41
+ (Settings → Developer settings → GitHub Apps → Your App → Private keys)
42
+ 2. Set the secret from the file:
43
+ gh secret set APP_PRIVATE_KEY < my-app.private-key.pem
44
+ 3. Verify the secret was stored correctly by checking the Actions secrets list shows
45
+ the key was updated recently
46
+
47
+ If the key is already in a secret and you cannot change it, create a new private key
48
+ from the App settings and re-set the secret from the fresh download.
49
+ fix_code:
50
+ - language: shell
51
+ label: "Set secret directly from downloaded .pem file (preserves newlines)"
52
+ code: |
53
+ # Download the .pem from GitHub App settings, then:
54
+ gh secret set APP_PRIVATE_KEY < my-app.2024-01-15.private-key.pem
55
+ - language: yaml
56
+ label: "Correct workflow: reference private key secret in action"
57
+ code: |
58
+ - uses: actions/create-github-app-token@v1
59
+ id: app-token
60
+ with:
61
+ app-id: ${{ vars.APP_ID }}
62
+ private-key: ${{ secrets.APP_PRIVATE_KEY }}
63
+
64
+ - name: Use generated token
65
+ run: echo "Token generated successfully"
66
+ env:
67
+ GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
68
+ prevention:
69
+ - "Always set the APP_PRIVATE_KEY secret using `gh secret set KEY < file.pem`, never by copy-pasting through the browser UI"
70
+ - "Regenerate and re-set the private key if you suspect formatting was corrupted during initial setup"
71
+ - "Verify the secret value in the GitHub UI shows the correct 'Updated' timestamp after setting via CLI"
72
+ - "Store private keys in a secrets manager (e.g., HashiCorp Vault, AWS Secrets Manager) and fetch at runtime to avoid manual copy-paste errors"
73
+ docs:
74
+ - url: "https://github.com/actions/create-github-app-token"
75
+ label: "actions/create-github-app-token README"
76
+ - url: "https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/generating-a-private-key-for-a-github-app"
77
+ label: "Generating a private key for a GitHub App"
78
+ - url: "https://github.com/actions/create-github-app-token/issues/153"
79
+ label: "actions/create-github-app-token#153: JWT decode error (27 comments)"
@@ -0,0 +1,84 @@
1
+ id: permissions-auth-022
2
+ title: "create-github-app-token: push rejected — GitHub App missing `workflows` permission"
3
+ category: permissions-auth
4
+ severity: error
5
+ tags:
6
+ - github-app
7
+ - create-github-app-token
8
+ - workflows-permission
9
+ - push
10
+ - git-push
11
+ patterns:
12
+ - regex: "refusing to allow a GitHub App to create or update workflow .+ without `workflows` permission"
13
+ flags: "i"
14
+ - regex: "remote rejected.*refusing to allow a GitHub App.*workflows.*permission"
15
+ flags: "i"
16
+ error_messages:
17
+ - "! [remote rejected] -> (refusing to allow a GitHub App to create or update workflow `.github/workflows/` without `workflows` permission)"
18
+ - "refusing to allow a GitHub App to create or update workflow `.github/workflows/my-workflow.yml` without `workflows` permission"
19
+ - "error: failed to push some refs to ''"
20
+ root_cause: |
21
+ When a workflow uses `actions/create-github-app-token` to generate a token and then uses
22
+ that token to push commits that include changes to `.github/workflows/` files, GitHub
23
+ enforces that the GitHub App's installation token has the `workflows` write permission.
24
+
25
+ This permission gate was tightened in `actions/create-github-app-token` v2.1.4 due to
26
+ changes in `octokit/auth-app.js` (PR #712). Tokens generated without explicitly requesting
27
+ the `workflows` write permission no longer inherit it automatically, even if the GitHub App
28
+ itself has the permission enabled in its settings.
29
+
30
+ Two things must be true for the push to succeed:
31
+ 1. The GitHub App has the `Workflows` repository permission set to Read & Write in the
32
+ App's settings page
33
+ 2. The `permission-workflows: write` input is passed to `actions/create-github-app-token`
34
+ so the generated token explicitly includes that permission
35
+ fix: |
36
+ Add `permission-workflows: write` to the `actions/create-github-app-token` step. Also
37
+ verify that the GitHub App itself has the Workflows permission enabled in its settings.
38
+
39
+ Steps:
40
+ 1. Go to https://github.com/settings/apps/YOUR_APP/permissions
41
+ 2. Under "Repository permissions", set "Workflows" to "Read and write"
42
+ 3. Save changes and accept the permission update for affected organizations/users
43
+ 4. Update your workflow to pass `permission-workflows: write`
44
+ fix_code:
45
+ - language: yaml
46
+ label: "Add workflows write permission to token generation step"
47
+ code: |
48
+ - uses: actions/create-github-app-token@v1
49
+ id: app-token
50
+ with:
51
+ app-id: ${{ vars.APP_ID }}
52
+ private-key: ${{ secrets.APP_PRIVATE_KEY }}
53
+ permission-workflows: write # ✅ Required when pushing workflow file changes
54
+
55
+ - name: Configure git with app token
56
+ run: |
57
+ git config user.name "github-actions[bot]"
58
+ git config user.email "github-actions[bot]@users.noreply.github.com"
59
+ git remote set-url origin https://x-access-token:${{ steps.app-token.outputs.token }}@github.com/${{ github.repository }}
60
+
61
+ - name: Push changes including workflow files
62
+ run: git push
63
+ - language: yaml
64
+ label: "Fallback: pin to v2.1.3 if immediate permission change is not possible"
65
+ code: |
66
+ # Pinning to a pre-v2.1.4 version is a temporary workaround only.
67
+ # Migrate to permission-workflows: write as soon as possible.
68
+ - uses: actions/create-github-app-token@v2.1.3
69
+ id: app-token
70
+ with:
71
+ app-id: ${{ vars.APP_ID }}
72
+ private-key: ${{ secrets.APP_PRIVATE_KEY }}
73
+ prevention:
74
+ - "Always specify `permission-workflows: write` when the token will be used to push `.github/workflows/` changes"
75
+ - "Verify the GitHub App's Workflows repository permission is set to Read & Write in the App settings"
76
+ - "Avoid pinning to old versions as a workaround — explicitly grant the required permission instead"
77
+ - "Use separate token generation steps with minimal permissions for each distinct operation"
78
+ docs:
79
+ - url: "https://github.com/actions/create-github-app-token"
80
+ label: "actions/create-github-app-token README"
81
+ - url: "https://docs.github.com/en/rest/authentication/permissions-required-for-github-apps?apiVersion=2022-11-28#repository-permissions-for-workflows"
82
+ label: "Permissions required for GitHub Apps — Workflows"
83
+ - url: "https://github.com/actions/create-github-app-token/issues/301"
84
+ label: "actions/create-github-app-token#301: workflows permission push rejection"
@@ -0,0 +1,105 @@
1
+ id: silent-failures-025
2
+ title: "attest-build-provenance: OCIError 404 when image not pushed to registry before attestation"
3
+ category: silent-failures
4
+ severity: error
5
+ tags:
6
+ - attest-build-provenance
7
+ - oci
8
+ - container-registry
9
+ - slsa
10
+ - attestation
11
+ - push-to-registry
12
+ patterns:
13
+ - regex: "OCIError: Error uploading artifact to container registry"
14
+ flags: "i"
15
+ - regex: "Error fetching .+/manifests/sha256:[a-f0-9]+ - expected 200, received 404"
16
+ flags: "i"
17
+ - regex: "expected 200, received 404"
18
+ flags: "i"
19
+ error_messages:
20
+ - "Error: OCIError: Error uploading artifact to container registry"
21
+ - "Error: Error fetching https://ghcr.io/v2/owner/repo/manifests/sha256:abc123... - expected 200, received 404"
22
+ root_cause: |
23
+ `actions/attest-build-provenance` with `push-to-registry: true` fetches the image manifest
24
+ from the container registry to embed it in the attestation bundle. If the image was built
25
+ with `load: true` in `docker/build-push-action` but `push: false` (or a conditional push
26
+ that evaluated to false), the image exists only in the runner's local Docker daemon — not
27
+ in the remote registry. The attestation step then fails with a 404 when fetching the
28
+ manifest from the registry URL.
29
+
30
+ This is a silent misconfiguration: the build step "succeeds" (because `load: true` works),
31
+ the attestation step then fails with a cryptic OCI/manifest error instead of a clear message
32
+ explaining that the image was never pushed.
33
+
34
+ Typical trigger: workflows that conditionally push (e.g., only on `main` branch) but run
35
+ the attestation step unconditionally on every push/PR.
36
+ fix: |
37
+ Guard the attestation step with the same `if:` condition used for the image push.
38
+ The attestation step should only run when the image was actually pushed to the registry.
39
+
40
+ If you need to generate attestations on PRs (e.g., for preview images), ensure the image
41
+ is actually pushed to a staging registry before the attestation step runs.
42
+ fix_code:
43
+ - language: yaml
44
+ label: "Wrong: attestation runs unconditionally even when image not pushed"
45
+ code: |
46
+ - name: Build and push
47
+ id: build-push
48
+ uses: docker/build-push-action@v6
49
+ with:
50
+ push: ${{ github.ref == 'refs/heads/main' }} # Only pushes on main
51
+ load: true
52
+ tags: ghcr.io/org/app:latest
53
+
54
+ - name: Generate attestation
55
+ uses: actions/attest-build-provenance@v2
56
+ with:
57
+ subject-name: ghcr.io/org/app
58
+ subject-digest: ${{ steps.build-push.outputs.digest }}
59
+ push-to-registry: true # ❌ Fails on PRs — image is local-only
60
+ - language: yaml
61
+ label: "Fix: match attestation if condition to the push condition"
62
+ code: |
63
+ - name: Build and push
64
+ id: build-push
65
+ uses: docker/build-push-action@v6
66
+ with:
67
+ push: ${{ github.ref == 'refs/heads/main' }}
68
+ load: true
69
+ tags: ghcr.io/org/app:latest
70
+
71
+ - name: Generate attestation
72
+ if: github.ref == 'refs/heads/main' # ✅ Same condition as push
73
+ uses: actions/attest-build-provenance@v2
74
+ with:
75
+ subject-name: ghcr.io/org/app
76
+ subject-digest: ${{ steps.build-push.outputs.digest }}
77
+ push-to-registry: true
78
+ - language: yaml
79
+ label: "Alternative: use push-to-registry: false for GitHub-only attestations"
80
+ code: |
81
+ - name: Build and push
82
+ id: build-push
83
+ uses: docker/build-push-action@v6
84
+ with:
85
+ push: true
86
+ tags: ghcr.io/org/app:latest
87
+
88
+ - name: Generate attestation (stored in GitHub, not registry)
89
+ uses: actions/attest-build-provenance@v2
90
+ with:
91
+ subject-name: ghcr.io/org/app
92
+ subject-digest: ${{ steps.build-push.outputs.digest }}
93
+ push-to-registry: false # ✅ Default; stores attestation in GitHub only
94
+ prevention:
95
+ - "Always guard `push-to-registry: true` attestation steps with the same `if:` condition used for the image push"
96
+ - "Remember: `load: true` in docker/build-push-action loads the image into the local Docker daemon only — it does not push to any registry"
97
+ - "Use `push-to-registry: false` (the default) when attestations only need to be verified via `gh attestation verify`, not via the registry manifest"
98
+ - "Set `push: ${{ steps.should-push.outputs.result }}` and reuse that output in the attestation step's `if:` condition to keep them in sync"
99
+ docs:
100
+ - url: "https://github.com/actions/attest-build-provenance"
101
+ label: "actions/attest-build-provenance README"
102
+ - url: "https://docs.github.com/en/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds"
103
+ label: "Using artifact attestations to establish provenance for builds"
104
+ - url: "https://github.com/actions/attest-build-provenance/issues/747"
105
+ label: "actions/attest-build-provenance#747: 404 when uploading artifact to container registry"
@@ -0,0 +1,106 @@
1
+ id: triggers-018
2
+ title: "workflow_run: download-artifact finds no artifacts without explicit run-id"
3
+ category: triggers
4
+ severity: silent-failure
5
+ tags:
6
+ - workflow_run
7
+ - download-artifact
8
+ - run-id
9
+ - cross-workflow
10
+ - artifact
11
+ patterns:
12
+ - regex: "No artifacts found"
13
+ flags: "i"
14
+ - regex: "Unable to find any artifacts for the associated workflow"
15
+ flags: "i"
16
+ - regex: "No artifacts were found with the provided run ID"
17
+ flags: "i"
18
+ error_messages:
19
+ - "No artifacts found"
20
+ - "Unable to find any artifacts for the associated workflow run"
21
+ - "Warning: No artifacts were found with the provided run ID."
22
+ - "Error: Unable to find any artifacts for the associated workflow run"
23
+ root_cause: |
24
+ When a workflow is triggered by the `workflow_run` event, it runs in the context of
25
+ **its own** workflow run — not the triggering workflow run. If `actions/download-artifact`
26
+ is called without specifying `run-id`, it defaults to `${{ github.run_id }}` which is the
27
+ ID of the triggered (consumer) workflow — not the upstream workflow that produced the
28
+ artifacts.
29
+
30
+ Since the consumer workflow produces no artifacts itself, `download-artifact` finds nothing.
31
+ This is a silent failure in some versions: the step exits without error but no files are
32
+ downloaded, causing subsequent steps that depend on the artifact to fail with confusing errors.
33
+
34
+ The artifact was uploaded in the triggering workflow's run. To download it, you must
35
+ explicitly reference `github.event.workflow_run.id` (the upstream run's ID).
36
+ fix: |
37
+ Add `run-id: ${{ github.event.workflow_run.id }}` to the `actions/download-artifact`
38
+ step. This tells the action to download from the triggering workflow run rather than
39
+ the current workflow run.
40
+
41
+ Also ensure the token has `actions: read` permission to download artifacts from other runs.
42
+ fix_code:
43
+ - language: yaml
44
+ label: "Wrong: download-artifact defaults to current run (finds nothing in workflow_run)"
45
+ code: |
46
+ on:
47
+ workflow_run:
48
+ workflows: ["CI"]
49
+ types: [completed]
50
+
51
+ jobs:
52
+ deploy:
53
+ runs-on: ubuntu-latest
54
+ steps:
55
+ - uses: actions/download-artifact@v4
56
+ with:
57
+ name: build-output # ❌ Defaults to github.run_id (this run, has no artifacts)
58
+ - language: yaml
59
+ label: "Fix: explicitly reference the triggering run's ID"
60
+ code: |
61
+ on:
62
+ workflow_run:
63
+ workflows: ["CI"]
64
+ types: [completed]
65
+
66
+ jobs:
67
+ deploy:
68
+ runs-on: ubuntu-latest
69
+ permissions:
70
+ actions: read # Required to download artifacts from other workflow runs
71
+ steps:
72
+ - uses: actions/download-artifact@v4
73
+ with:
74
+ name: build-output
75
+ run-id: ${{ github.event.workflow_run.id }} # ✅ The upstream run's ID
76
+ - language: yaml
77
+ label: "Guard: only run if triggering workflow succeeded"
78
+ code: |
79
+ on:
80
+ workflow_run:
81
+ workflows: ["CI"]
82
+ types: [completed]
83
+
84
+ jobs:
85
+ deploy:
86
+ if: github.event.workflow_run.conclusion == 'success' # ✅ Don't deploy on failure
87
+ runs-on: ubuntu-latest
88
+ permissions:
89
+ actions: read
90
+ steps:
91
+ - uses: actions/download-artifact@v4
92
+ with:
93
+ name: build-output
94
+ run-id: ${{ github.event.workflow_run.id }}
95
+ prevention:
96
+ - "Always specify `run-id: ${{ github.event.workflow_run.id }}` when downloading artifacts in a `workflow_run`-triggered workflow"
97
+ - "Add `permissions: actions: read` to any job that downloads artifacts from a different workflow run"
98
+ - "Guard the job with `if: github.event.workflow_run.conclusion == 'success'` to skip on upstream failures"
99
+ - "Use `github.event.workflow_run.id` (not `github.run_id`) — they are different: the former is the upstream run, the latter is the current consumer run"
100
+ docs:
101
+ - url: "https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#workflow_run"
102
+ label: "Events that trigger workflows — workflow_run"
103
+ - url: "https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/storing-and-sharing-data-from-a-workflow#downloading-artifacts-from-a-different-workflow-run"
104
+ label: "Downloading artifacts from a different workflow run"
105
+ - url: "https://github.com/actions/download-artifact"
106
+ label: "actions/download-artifact README"
@@ -0,0 +1,102 @@
1
+ id: yaml-syntax-023
2
+ title: "Reusable workflow: env context rejected in `jobs.<job_id>.with` inputs"
3
+ category: yaml-syntax
4
+ severity: error
5
+ tags:
6
+ - reusable-workflow
7
+ - env-context
8
+ - with-inputs
9
+ - workflow_call
10
+ - variable-scoping
11
+ patterns:
12
+ - regex: "Unrecognized named-value: 'env'"
13
+ flags: "i"
14
+ - regex: "Context access might be invalid: env"
15
+ flags: "i"
16
+ - regex: "The env context is not available"
17
+ flags: "i"
18
+ error_messages:
19
+ - "Unrecognized named-value: 'env'. Located at position 1 within expression: env.MY_VAR"
20
+ - "Context access might be invalid: env"
21
+ - "The env context is not available to reusable workflow inputs"
22
+ root_cause: |
23
+ When calling a reusable workflow using `jobs.<job_id>.uses`, the `env` context is not
24
+ available inside the `with:` block. Only the following contexts are permitted at that
25
+ evaluation point: `github`, `inputs`, `needs`, `strategy`, and `matrix`.
26
+
27
+ This is a platform-level restriction. The `env` context is resolved during job execution
28
+ on the runner, but reusable workflow `with:` inputs are evaluated at workflow dispatch time
29
+ (before a runner is allocated), so `env` values are simply unavailable.
30
+
31
+ Top-level `env:` blocks defined in the caller workflow cannot be referenced inside
32
+ `jobs.<job_id>.with` — using `${{ env.MY_VAR }}` there produces a syntax validation
33
+ error that prevents the workflow from running at all.
34
+ fix: |
35
+ Replace `${{ env.MY_VAR }}` in reusable workflow `with:` inputs with one of:
36
+
37
+ 1. `${{ vars.MY_VAR }}` — repository or organization variable (preferred for non-secret
38
+ configuration values that are reused across workflows)
39
+ 2. Hardcoded literal value directly in `with:`
40
+ 3. An intermediate job that exposes the value as a job output, then reference it via
41
+ `${{ needs.prepare.outputs.my_var }}`
42
+ fix_code:
43
+ - language: yaml
44
+ label: "Wrong: env context in reusable workflow with inputs"
45
+ code: |
46
+ env:
47
+ DEPLOY_ENV: "production"
48
+
49
+ jobs:
50
+ deploy:
51
+ uses: org/repo/.github/workflows/deploy.yml@main
52
+ with:
53
+ environment: ${{ env.DEPLOY_ENV }} # ❌ Error: env context not available
54
+ - language: yaml
55
+ label: "Fix option 1: use vars context (repository/org variable)"
56
+ code: |
57
+ jobs:
58
+ deploy:
59
+ uses: org/repo/.github/workflows/deploy.yml@main
60
+ with:
61
+ environment: ${{ vars.DEPLOY_ENV }} # ✅ vars context works in with:
62
+ - language: yaml
63
+ label: "Fix option 2: propagate via intermediate job output"
64
+ code: |
65
+ env:
66
+ DEPLOY_ENV: "production"
67
+
68
+ jobs:
69
+ prepare:
70
+ runs-on: ubuntu-latest
71
+ outputs:
72
+ deploy_env: ${{ steps.set-env.outputs.value }}
73
+ steps:
74
+ - id: set-env
75
+ run: echo "value=$DEPLOY_ENV" >> "$GITHUB_OUTPUT"
76
+
77
+ deploy:
78
+ needs: prepare
79
+ uses: org/repo/.github/workflows/deploy.yml@main
80
+ with:
81
+ environment: ${{ needs.prepare.outputs.deploy_env }} # ✅
82
+ - language: yaml
83
+ label: "Fix option 3: hardcode the value directly"
84
+ code: |
85
+ jobs:
86
+ deploy:
87
+ uses: org/repo/.github/workflows/deploy.yml@main
88
+ with:
89
+ environment: "production" # ✅ Literal values always work
90
+ prevention:
91
+ - "Store workflow-wide configuration values in repository or organization variables (`vars` context) so they are available in reusable workflow `with:` blocks"
92
+ - "Only `github`, `inputs`, `needs`, `strategy`, and `matrix` contexts are available in `jobs.<job_id>.with` — never `env`, `secrets`, or `steps`"
93
+ - "If a value must be computed at runtime, use an intermediate job with `outputs:` and reference via `needs.<job_id>.outputs.<key>`"
94
+ docs:
95
+ - url: "https://docs.github.com/en/actions/sharing-automations/reusing-workflows#limitations"
96
+ label: "Reusing workflows — Limitations"
97
+ - url: "https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/contexts#context-availability"
98
+ label: "GitHub Actions context availability by workflow key"
99
+ - url: "https://github.com/actions/runner/issues/1413"
100
+ label: "actions/runner#1413: env not available in reusable workflow with inputs (known limitation)"
101
+ - url: "https://github.com/actions/toolkit/issues/931"
102
+ label: "actions/toolkit#931: Variable scoping across reusable workflows (58 reactions)"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@htekdev/actions-debugger",
3
- "version": "1.0.18",
3
+ "version": "1.0.19",
4
4
  "description": "65+ real GitHub Actions errors, queryable by agents. MCP server + Copilot skills + error database.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",