Repository navigation
Description
Summary
Any workflow using checkout: with multi: true finishes every run with a failed job, even when the agent, the safe outputs and the pull request all succeed. The failure is in the Post Checkout runtime repositories (N) step:
Can't find 'action.yml', 'action.yaml' or 'Dockerfile' under
'/home/runner/work/<repo>/<repo>/.gh-aw/checkouts/1'.
Did you forget to run actions/checkout before running your local action?
Both the agent job and the safe_outputs job fail this way in the same run. safe_outputs never invokes the agent, which rules out anything the agent does to the workspace.
Root cause
actions/setup/js/checkout_dynamic.cjs:
prepare()writes a generated composite action to.gh-aw/checkouts/<index>/action.yml, whose steps areuses: actions/checkout@<sha>.- The compiled job runs it with
uses: ./.gh-aw/checkouts/<index>. actions/checkoutregisters a post hook. Because it is nested inside a composite action, the runner must re-resolve the composite'saction.ymlwhen the post phase runs at the end of the job.finish()deletes that file unconditionally:
const actionDir = workspacePath(config.workspace, `.gh-aw/checkouts/${config.index}`);
try {
fs.unlinkSync(path.join(actionDir, "action.yml"));
fs.rmdirSync(actionDir);
} catch (error) {
throw new Error("Unable to remove the temporary runtime checkout action", { cause: error });
}- The post phase fires, cannot resolve the path, and the job is marked failed.
The deletion itself looks intentional and correct — the generated action.yml carries a token: reference and should not outlive the checkout. The problem is that it is unconditional, with nothing accounting for the post hook it strands.
This is the same class of problem as #51448 (Post Setup Scripts on a since-removed composite path), but a different instance: that one was the evals job's actions/setup, this one is the generated runtime-checkout action, and it reproduces on every run rather than intermittently.
Versions
Not a regression, and not fixed on the current release. The code above is identical in v0.92.0 and v1.0.1 (actions/setup/js/checkout_dynamic.cjs, finish()), so the bug should affect every version in that range.
Reproduction
A workflow_dispatch workflow with a second checkout entry:
checkout:
- fetch-depth: 1
- repo: ${{ inputs.repository }}
multi: true
allowed-repos: my-org/*
max-repos: 1
path: target
github-token: ${{ secrets.A_READ_ONLY_PAT }}Compile and dispatch. The agent runs, the safe output lands, and both agent and safe_outputs still end red on Post Checkout runtime repositories (1).
Impact
The run's conclusion no longer carries information: a fully successful run and a genuinely broken one both show red. For a scheduled or frequently dispatched workflow that trains people to ignore the status, which is the signal you need to notice a real failure.
Possible fixes
- Keep a minimal no-op
action.ymlin place (notoken:reference) instead of removing the file, so the post phase resolves and does nothing. - Or have
prepare()emit steps that do not register a post hook, so there is nothing to strand. - Or restore the file for the post phase and remove the directory after the job.
Activity
niebloomj commentedon Nov 5, 2026
Additional reproduction evidence:
checkout: multi: trueboth failed inPost Checkout runtime repositories (1).checkout:entry, so it does not show that the multi-checkout path worked.The repeated result points to a lifecycle failure on the multi-checkout path rather than a sporadic engine failure: the temporary composite manifest is removed before the checkout post-hook can reload it.
niebloomj commentedon Nov 6, 2026
Status update: upstream PR #75381 now contains the lifecycle fix at head
2bf646339c61a6d49c2aa8f667858630ef6c8c46; its JS test shards, typecheck, lint, and checkout-cache checks pass. The PR remains open and GitHub reportsCHANGES_REQUESTED/BLOCKED, so the fix is not merged. Skills natural run 42168534512 reproduced the post-checkout failure before this PR and is not recovery evidence. Please keep this issue open until a natural post-merge run exercisescheckout: multi: truesuccessfully; no workflow was dispatched or rerun.