From 786d90a3e42256e2fe3867d7818ab422649e45e9 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 19 Mar 2026 16:11:07 +0000
Subject: [PATCH 1/2] debug: analysis of issue-monster pre_activation failure
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
---
.github/workflows/smoke-claude.lock.yml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml
index a339fc73b7..bceba229df 100644
--- a/.github/workflows/smoke-claude.lock.yml
+++ b/.github/workflows/smoke-claude.lock.yml
@@ -2629,6 +2629,8 @@ jobs:
///
// Auto-generated safe-output script handler: post-slack-message
+ const { sanitizeContent } = require("./sanitize_content.cjs");
+
/** @type {import('./types/safe-output-script').SafeOutputScriptMain} */
async function main(config = {}) {
const { channel, message } = config;
From d5a1a64dc933e7a215ba0ed3dae2fb515c289b0d Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 19 Mar 2026 16:23:52 +0000
Subject: [PATCH 2/2] fix: make pre-activation app token step resilient to
missing app installation
Add continue-on-error: true to the GitHub App token mint step in the
pre-activation job, and fall back to github.token in skip-if check steps
when the app token is empty (e.g. app not installed on the repository).
This fixes the Issue Monster workflow which has been failing for hundreds of
runs because the GitHub App (vars.APP_ID) is not installed on github/gh-aw:
the token generation returned HTTP 404, hard-failing pre_activation and
causing all downstream jobs to be skipped.
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
---
.github/workflows/issue-monster.lock.yml | 5 +++--
pkg/workflow/compiler_pre_activation_job.go | 7 ++++++-
pkg/workflow/skip_if_match_test.go | 6 +++---
pkg/workflow/skip_if_no_match_test.go | 12 ++++++------
4 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/.github/workflows/issue-monster.lock.yml b/.github/workflows/issue-monster.lock.yml
index efd91245e3..b35095a56c 100644
--- a/.github/workflows/issue-monster.lock.yml
+++ b/.github/workflows/issue-monster.lock.yml
@@ -1385,6 +1385,7 @@ jobs:
await main();
- name: Generate GitHub App token for skip-if checks
id: pre-activation-app-token
+ continue-on-error: true
uses: actions/create-github-app-token@a7f885bf4560200d03183ed941cb6fb072e4b343 # v3.0.0-beta.4
with:
app-id: ${{ vars.APP_ID }}
@@ -1400,7 +1401,7 @@ jobs:
GH_AW_WORKFLOW_NAME: "Issue Monster"
GH_AW_SKIP_MAX_MATCHES: "5"
with:
- github-token: ${{ steps.pre-activation-app-token.outputs.token }}
+ github-token: ${{ steps.pre-activation-app-token.outputs.token || github.token }}
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
setupGlobals(core, github, context, exec, io);
@@ -1414,7 +1415,7 @@ jobs:
GH_AW_WORKFLOW_NAME: "Issue Monster"
GH_AW_SKIP_MIN_MATCHES: "1"
with:
- github-token: ${{ steps.pre-activation-app-token.outputs.token }}
+ github-token: ${{ steps.pre-activation-app-token.outputs.token || github.token }}
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
setupGlobals(core, github, context, exec, io);
diff --git a/pkg/workflow/compiler_pre_activation_job.go b/pkg/workflow/compiler_pre_activation_job.go
index a049bd2592..df7c206a99 100644
--- a/pkg/workflow/compiler_pre_activation_job.go
+++ b/pkg/workflow/compiler_pre_activation_job.go
@@ -482,12 +482,15 @@ func (c *Compiler) extractPreActivationCustomFields(jobs map[string]any) ([]stri
// buildPreActivationAppTokenMintStep generates a single GitHub App token mint step for use
// by all skip-if checks in the pre-activation job. The step ID is "pre-activation-app-token".
// Auth configuration comes from the top-level on.github-app field.
+// The step uses continue-on-error: true so that a missing app installation (HTTP 404) does not
+// fail the pre-activation job; skip-if checks fall back to github.token in that case.
func (c *Compiler) buildPreActivationAppTokenMintStep(app *GitHubAppConfig) []string {
var steps []string
tokenStepID := constants.PreActivationAppTokenStepID
steps = append(steps, " - name: Generate GitHub App token for skip-if checks\n")
steps = append(steps, fmt.Sprintf(" id: %s\n", tokenStepID))
+ steps = append(steps, " continue-on-error: true\n")
steps = append(steps, fmt.Sprintf(" uses: %s\n", GetActionPin("actions/create-github-app-token")))
steps = append(steps, " with:\n")
steps = append(steps, fmt.Sprintf(" app-id: %s\n", app.AppID))
@@ -520,9 +523,11 @@ func (c *Compiler) buildPreActivationAppTokenMintStep(app *GitHubAppConfig) []st
// resolvePreActivationSkipIfToken returns the GitHub token expression to use for skip-if check
// steps in the pre-activation job. Priority: App token > custom github-token > empty (default).
// When non-empty, callers should emit `with.github-token: ` in the step.
+// When an app is configured the token step uses continue-on-error: true, so the expression
+// falls back to github.token in case the app is not installed on the repository.
func (c *Compiler) resolvePreActivationSkipIfToken(data *WorkflowData) string {
if data.ActivationGitHubApp != nil {
- return fmt.Sprintf("${{ steps.%s.outputs.token }}", constants.PreActivationAppTokenStepID)
+ return fmt.Sprintf("${{ steps.%s.outputs.token || github.token }}", constants.PreActivationAppTokenStepID)
}
if data.ActivationGitHubToken != "" {
return data.ActivationGitHubToken
diff --git a/pkg/workflow/skip_if_match_test.go b/pkg/workflow/skip_if_match_test.go
index 2d1ffc7a64..05e1ea214c 100644
--- a/pkg/workflow/skip_if_match_test.go
+++ b/pkg/workflow/skip_if_match_test.go
@@ -440,9 +440,9 @@ This workflow uses a GitHub App token for org-wide search.
t.Error("Expected owner to be set in GitHub App token mint step")
}
- // Verify the minted token is used in the skip-if step via the unified step ID
- if !strings.Contains(lockContentStr, "github-token: ${{ steps.pre-activation-app-token.outputs.token }}") {
- t.Error("Expected minted app token (pre-activation-app-token) to be used in skip-if-match step")
+ // Verify the minted token is used in the skip-if step via the unified step ID (with github.token fallback)
+ if !strings.Contains(lockContentStr, "github-token: ${{ steps.pre-activation-app-token.outputs.token || github.token }}") {
+ t.Error("Expected minted app token (pre-activation-app-token) with github.token fallback to be used in skip-if-match step")
}
// Verify GH_AW_SKIP_SCOPE is set to "none"
diff --git a/pkg/workflow/skip_if_no_match_test.go b/pkg/workflow/skip_if_no_match_test.go
index 6f4abb5d61..b73b20a138 100644
--- a/pkg/workflow/skip_if_no_match_test.go
+++ b/pkg/workflow/skip_if_no_match_test.go
@@ -499,9 +499,9 @@ This workflow uses a GitHub App token for org-wide search.
t.Error("Expected owner to be set in GitHub App token mint step")
}
- // Verify the minted token is used in the skip-if step via the unified step ID
- if !strings.Contains(lockContentStr, "github-token: ${{ steps.pre-activation-app-token.outputs.token }}") {
- t.Error("Expected minted app token (pre-activation-app-token) to be used in skip-if-no-match step")
+ // Verify the minted token is used in the skip-if step via the unified step ID (with github.token fallback)
+ if !strings.Contains(lockContentStr, "github-token: ${{ steps.pre-activation-app-token.outputs.token || github.token }}") {
+ t.Error("Expected minted app token (pre-activation-app-token) with github.token fallback to be used in skip-if-no-match step")
}
// Verify GH_AW_SKIP_SCOPE is set to "none"
@@ -563,9 +563,9 @@ Both skip-if-match and skip-if-no-match share one mint step.
if !strings.Contains(lockContentStr, "Check skip-if-no-match query") {
t.Error("Expected skip-if-no-match check to be present")
}
- // Both reference the same pre-activation-app-token step
- if strings.Count(lockContentStr, "github-token: ${{ steps.pre-activation-app-token.outputs.token }}") != 2 {
- t.Error("Expected both skip-if steps to reference the unified pre-activation-app-token step")
+ // Both reference the same pre-activation-app-token step (with github.token fallback)
+ if strings.Count(lockContentStr, "github-token: ${{ steps.pre-activation-app-token.outputs.token || github.token }}") != 2 {
+ t.Error("Expected both skip-if steps to reference the unified pre-activation-app-token step with github.token fallback")
}
})
}