Problem
When a reusable workflow is called cross-org via workflow_call, the activation job's "Checkout .github and .agents folders" step and "Check workflow lock file" step both use the default GITHUB_TOKEN. Since GITHUB_TOKEN is scoped to the caller's repo, it cannot access the callee's repo contents cross-org.
The on.github-token frontmatter field exists specifically for cross-org scenarios — it's already wired to resolveActivationToken() and correctly propagated to the reaction, status comment, and label removal steps. However, the checkout and hash check steps don't use it.
Cascading failure
- Sparse checkout fails silently —
actions/checkout has no token: override, so it can't clone the callee's .github folder cross-org.
- Hash check API returns 404 —
check_workflow_timestamp_api.cjs uses the default token, which can't read the callee repo via API.
- Local filesystem fallback fails — falls back to
$GITHUB_WORKSPACE, but the callee's files aren't there (because step 1 failed).
- Result:
ERR_CONFIG: Lock file is outdated or unverifiable — false positive that blocks the workflow.
Observed behavior (debug logs)
Cross-repo invocation detected: workflow source is "<callee-org>/<callee-repo>",
current repo is "<caller-org>/<caller-repo>"
GET /repos/<callee-org>/<callee-repo>/contents/.github/workflows/<name>.lock.yml - 404
Unable to fetch lock file content for hash comparison via API, trying local filesystem fallback
Local lock file not found: /home/runner/work/<caller-repo>/<caller-repo>/.github/workflows/<name>.lock.yml
Warning: Could not compare frontmatter hashes - assuming lock file is outdated
Error: ERR_CONFIG: Lock file '<name>.lock.yml' is outdated or unverifiable!
Affected code
1. pkg/workflow/checkout_step_generator.go — GenerateGitHubFolderCheckoutStep()
Never emits a token: field, even when checking out a cross-repo target:
if repository != "" {
fmt.Fprintf(&sb, " repository: %s\n", repository)
}
// No token: field emitted — defaults to GITHUB_TOKEN
2. pkg/workflow/compiler_activation_job.go — "Check workflow lock file" step
Does not call resolveActivationToken(data), unlike the reaction and comment steps:
steps = append(steps, " with:\n")
steps = append(steps, " script: |\n")
// No github-token: emitted — defaults to GITHUB_TOKEN
Suggested fix
-
Checkout step: Accept an optional token parameter in GenerateGitHubFolderCheckoutStep() and emit token: when it's not the default GITHUB_TOKEN.
-
Hash check step: Use the same resolveActivationToken(data) pattern already used by the reaction and comment steps:
hashToken := c.resolveActivationToken(data)
if hashToken != "${{ secrets.GITHUB_TOKEN }}" {
steps = append(steps, fmt.Sprintf(" github-token: %s\n", hashToken))
}
What this fixes
Eliminates the need for consumers to manually patch compiled lock files for cross-org workflow_call. Users would configure on.github-token in their .md frontmatter (which many already do for reactions/comments), and the compiler would propagate it to all activation steps that need callee repo access.
What this does NOT fix
Users will still need to provide a cross-org token (PAT or GitHub App) via on.github-token and pass it as a secret from the caller. This is a platform constraint — GITHUB_TOKEN is repo-scoped and cannot access other repos regardless of visibility.
Workaround
Manually inject github-token: ${{ secrets.CROSS_ORG_TOKEN || github.token }} into the compiled .lock.yml after every gh aw compile. This must be re-applied after every recompilation.
Problem
When a reusable workflow is called cross-org via
workflow_call, the activation job's "Checkout .github and .agents folders" step and "Check workflow lock file" step both use the defaultGITHUB_TOKEN. SinceGITHUB_TOKENis scoped to the caller's repo, it cannot access the callee's repo contents cross-org.The
on.github-tokenfrontmatter field exists specifically for cross-org scenarios — it's already wired toresolveActivationToken()and correctly propagated to the reaction, status comment, and label removal steps. However, the checkout and hash check steps don't use it.Cascading failure
actions/checkouthas notoken:override, so it can't clone the callee's.githubfolder cross-org.check_workflow_timestamp_api.cjsuses the default token, which can't read the callee repo via API.$GITHUB_WORKSPACE, but the callee's files aren't there (because step 1 failed).ERR_CONFIG: Lock file is outdated or unverifiable— false positive that blocks the workflow.Observed behavior (debug logs)
Affected code
1.
pkg/workflow/checkout_step_generator.go—GenerateGitHubFolderCheckoutStep()Never emits a
token:field, even when checking out a cross-repo target:2.
pkg/workflow/compiler_activation_job.go— "Check workflow lock file" stepDoes not call
resolveActivationToken(data), unlike the reaction and comment steps:Suggested fix
Checkout step: Accept an optional token parameter in
GenerateGitHubFolderCheckoutStep()and emittoken:when it's not the defaultGITHUB_TOKEN.Hash check step: Use the same
resolveActivationToken(data)pattern already used by the reaction and comment steps:What this fixes
Eliminates the need for consumers to manually patch compiled lock files for cross-org
workflow_call. Users would configureon.github-tokenin their.mdfrontmatter (which many already do for reactions/comments), and the compiler would propagate it to all activation steps that need callee repo access.What this does NOT fix
Users will still need to provide a cross-org token (PAT or GitHub App) via
on.github-tokenand pass it as a secret from the caller. This is a platform constraint —GITHUB_TOKENis repo-scoped and cannot access other repos regardless of visibility.Workaround
Manually inject
github-token: ${{ secrets.CROSS_ORG_TOKEN || github.token }}into the compiled.lock.ymlafter everygh aw compile. This must be re-applied after every recompilation.