Bug
When a workflow configures safe-outputs.push-to-pull-request-branch.target-repo without also configuring safe-outputs.create-pull-request, the compiler-emitted safe_outputs job checks out the workflow repo instead of the target repo. The handler's git ls-remote --exit-code --heads origin <pr-branch> then fails with exit code 2 because origin points at the wrong repository.
This is the exact gap PR #22244 set out to fix. That PR was closed without merge on 2026-03-22; PR #28388 (which closed tracking issue #21306) only fixed the JS handler's directory handling, not the Go compiler step generation. As a result, the regression is still present on main (verified at HEAD of pkg/workflow/compiler_safe_outputs_steps.go) and against gh-aw extension v0.71.5.
Repro
Workflow config (abbreviated, real workflow at microsoft/vscode-engineering/.github/workflows/errors-fix-driver.md):
on:
workflow_dispatch:
inputs:
pr_number: { type: string, required: true }
safe-outputs:
github-token: ${{ steps.safe-outputs-app-token.outputs.token }}
push-to-pull-request-branch:
target-repo: "microsoft/vscode"
update-pull-request:
target-repo: "microsoft/vscode"
# NOTE: no create-pull-request configured
tools:
github:
github-token: ${{ steps.safe-outputs-app-token.outputs.token }}
# checkout block puts target repo at workspace root
# (workflow repo is at ./workflow-repo)
The compiled safe_outputs job emits:
- name: Checkout repository
if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'push_to_pull_request_branch')
uses: actions/checkout@...
with:
ref: ${{ github.base_ref || ... }}
token: ${{ steps.safe-outputs-app-token.outputs.token }}
persist-credentials: false
fetch-depth: 1
# <-- repository: missing
- name: Configure Git credentials
env:
REPO_NAME: ${{ github.repository }} # <-- wrong repo (vscode-engineering, not vscode)
...
run: |
git remote set-url origin "https://x-access-token:${GIT_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
The handler actions/setup/js/push_to_pull_request_branch.cjs then runs:
git ls-remote --exit-code --heads origin fix/listview-null-row-guard-314134-...
against origin = microsoft/vscode-engineering, exits with code 2, and fails the job.
Root cause (source)
pkg/workflow/compiler_safe_outputs_steps.go::buildSharedPRCheckoutSteps only consults CreatePullRequests.TargetRepoSlug when picking targetRepoSlug:
// Priority: create-pull-request target-repo > trialLogicalRepoSlug > default (source repo)
var targetRepoSlug string
if data.SafeOutputs.CreatePullRequests != nil &&
data.SafeOutputs.CreatePullRequests.TargetRepoSlug != "" {
targetRepoSlug = data.SafeOutputs.CreatePullRequests.TargetRepoSlug
} else if c.trialMode && c.trialLogicalRepoSlug != "" {
targetRepoSlug = c.trialLogicalRepoSlug
}
// missing: PushToPullRequestBranch.TargetRepoSlug fallback
REPO_NAME and repository: are then both elided from the emitted YAML. The same is true for UpdatePullRequest.TargetRepoSlug, which has identical semantics for cross-repo updates.
Expected
When any of the following are set (and create-pull-request is not), the safe_outputs job should check out the configured target repo and set REPO_NAME accordingly:
push-to-pull-request-branch.target-repo
update-pull-request.target-repo (same problem class)
PR #22244's CheckoutManager-based design (each safe output independently registers its checkout requirement, manager dedupes) is the right shape; that PR just never landed.
Workaround
Add a no-op create-pull-request to safe-outputs purely to trick the compiler — undesirable because it changes runtime guards/permissions and risks accidental PR creation.
Affected versions
- gh-aw extension v0.71.1 → v0.71.5 (current). Compiler
main HEAD as of 2026-05-05 still has the gap.
Related
Bug
When a workflow configures
safe-outputs.push-to-pull-request-branch.target-repowithout also configuringsafe-outputs.create-pull-request, the compiler-emittedsafe_outputsjob checks out the workflow repo instead of the target repo. The handler'sgit ls-remote --exit-code --heads origin <pr-branch>then fails with exit code 2 becauseoriginpoints at the wrong repository.This is the exact gap PR #22244 set out to fix. That PR was closed without merge on 2026-03-22; PR #28388 (which closed tracking issue #21306) only fixed the JS handler's directory handling, not the Go compiler step generation. As a result, the regression is still present on
main(verified at HEAD ofpkg/workflow/compiler_safe_outputs_steps.go) and against gh-aw extension v0.71.5.Repro
Workflow config (abbreviated, real workflow at
microsoft/vscode-engineering/.github/workflows/errors-fix-driver.md):The compiled
safe_outputsjob emits:The handler
actions/setup/js/push_to_pull_request_branch.cjsthen runs:against
origin = microsoft/vscode-engineering, exits with code 2, and fails the job.Root cause (source)
pkg/workflow/compiler_safe_outputs_steps.go::buildSharedPRCheckoutStepsonly consultsCreatePullRequests.TargetRepoSlugwhen pickingtargetRepoSlug:REPO_NAMEandrepository:are then both elided from the emitted YAML. The same is true forUpdatePullRequest.TargetRepoSlug, which has identical semantics for cross-repo updates.Expected
When any of the following are set (and
create-pull-requestis not), thesafe_outputsjob should check out the configured target repo and setREPO_NAMEaccordingly:push-to-pull-request-branch.target-repoupdate-pull-request.target-repo(same problem class)PR #22244's
CheckoutManager-based design (each safe output independently registers its checkout requirement, manager dedupes) is the right shape; that PR just never landed.Workaround
Add a no-op
create-pull-requestto safe-outputs purely to trick the compiler — undesirable because it changes runtime guards/permissions and risks accidental PR creation.Affected versions
mainHEAD as of 2026-05-05 still has the gap.Related
push_to_pull_request_branchin the JS handler. Compiler-side gap was out of scope.push_to_pull_request_branchis supported whentarget-repois set — but the compiler does not honor it withoutcreate-pull-request.