Summary
push_to_pull_request_branch has no repo (or target-repo) input, so in a multi-repo workflow where several repos are checked out into subdirectories and the safe output uses target: "*", the handler cannot determine which sub-repo checkout a PR lives in. It always runs git from GITHUB_WORKSPACE (the primary/root checkout) and fails when the PR's branch only exists in a sub-repo checkout.
Filed by @heiskr (with GitHub Copilot). I couldn't fully dedupe against existing issues because the search API was returning 503s at filing time — please close as duplicate if one exists.
Repro
A workflow checks out 7 repos into subdirectories (docs-internal/, docs-content/, ...), GITHUB_WORKSPACE is the primary repo root, and:
safe-outputs:
push-to-pull-request-branch:
target: "*"
allowed-repos: [github/docs-internal, github/docs-content, ...]
The agent commits to a branch inside one sub-repo checkout (e.g. docs-internal/), then calls push_to_pull_request_branch(pull_request_number: 62133, branch: fix-...). It fails:
git rev-parse fails with 'Needed a single revision'
because <branch> only exists in docs-internal/ checkout
Root cause
In actions/setup/js/safe_outputs_tools.json, the tool's input schema is [message, branch, pull_request_number, secrecy, integrity] — no repo — and x-safe-outputs-target-requirements["*"] is { primary: pull_request_number, anyOf: [pull_request_number] }.
In actions/setup/js/safe_outputs_handlers.cjs, the push handler resolves the working directory only when a repo is known:
if (((entry.repo && entry.repo.trim()) || pushConfig["target-repo"]) && !repoCwd) {
const checkoutResult = findRepoCheckout(itemRepo); // resolves sub-repo checkout dir
...
}
For target: "*", pushConfig["target-repo"] is empty and the tool never supplies entry.repo, so this branch never runs. repoCwd stays null and every git op runs from GITHUB_WORKSPACE.
Contrast: create_pull_request works
create_pull_request does expose a repo param and reaches findRepoCheckout(repoSlug) via entry.repo, so it correctly targets sub-repo checkouts. push_to_pull_request_branch is missing the equivalent.
Proposed fix
Add a repo (owner/repo) input to push_to_pull_request_branch, mirroring create_pull_request, and include it in the wildcard anyOf so the agent must supply it when target: "*". Then findRepoCheckout(itemRepo) can resolve the correct sub-repo checkout. pull_request_number alone is ambiguous across repos.
Version
gh-aw v0.82.11 (latest at time of filing). Handler is unchanged from v0.82.7.
Real-world impact
github/docs-team's pr-janitor-agent scans and fixes PRs across 7 docs repos; cross-repo pushes fail every run. Tracked downstream in github/docs-team#7104.
Summary
push_to_pull_request_branchhas norepo(ortarget-repo) input, so in a multi-repo workflow where several repos are checked out into subdirectories and the safe output usestarget: "*", the handler cannot determine which sub-repo checkout a PR lives in. It always runs git fromGITHUB_WORKSPACE(the primary/root checkout) and fails when the PR's branch only exists in a sub-repo checkout.Filed by @heiskr (with GitHub Copilot). I couldn't fully dedupe against existing issues because the search API was returning 503s at filing time — please close as duplicate if one exists.
Repro
A workflow checks out 7 repos into subdirectories (
docs-internal/,docs-content/, ...),GITHUB_WORKSPACEis the primary repo root, and:The agent commits to a branch inside one sub-repo checkout (e.g.
docs-internal/), then callspush_to_pull_request_branch(pull_request_number: 62133, branch: fix-...). It fails:Root cause
In
actions/setup/js/safe_outputs_tools.json, the tool's input schema is[message, branch, pull_request_number, secrecy, integrity]— norepo— andx-safe-outputs-target-requirements["*"]is{ primary: pull_request_number, anyOf: [pull_request_number] }.In
actions/setup/js/safe_outputs_handlers.cjs, the push handler resolves the working directory only when a repo is known:For
target: "*",pushConfig["target-repo"]is empty and the tool never suppliesentry.repo, so this branch never runs.repoCwdstays null and every git op runs fromGITHUB_WORKSPACE.Contrast:
create_pull_requestworkscreate_pull_requestdoes expose arepoparam and reachesfindRepoCheckout(repoSlug)viaentry.repo, so it correctly targets sub-repo checkouts.push_to_pull_request_branchis missing the equivalent.Proposed fix
Add a
repo(owner/repo) input topush_to_pull_request_branch, mirroringcreate_pull_request, and include it in the wildcardanyOfso the agent must supply it whentarget: "*". ThenfindRepoCheckout(itemRepo)can resolve the correct sub-repo checkout.pull_request_numberalone is ambiguous across repos.Version
gh-aw v0.82.11 (latest at time of filing). Handler is unchanged from v0.82.7.
Real-world impact
github/docs-team's
pr-janitor-agentscans and fixes PRs across 7 docs repos; cross-repo pushes fail every run. Tracked downstream in github/docs-team#7104.