Summary
When the safe-outputs handler uses the bundle-based push path (introduced in CLI v0.72.1 / AWF v0.25.41), #aw_ temporary ID references in committed file contents are not resolved to real issue/PR numbers. The patch-based path correctly performs this substitution.
Reproduction
Two workflow runs of the same workflow (dotnet/aspnetcore daily test quarantine) demonstrate the regression:
|
✅ Working (May 15) |
❌ Broken (May 17) |
| Run |
25913878755 |
25988389764 |
| CLI version |
v0.71.5 |
v0.72.1 |
| AWF version |
v0.25.40 |
v0.25.41 |
| Change delivery |
.patch file |
.bundle file |
| Substitution log |
Resolved temporary ID references in patch content |
(missing — never logged) |
| Result |
PR #66694 — real issue number in code |
PR #66711 — literal #aw_redirect1 in code |
Working run (patch path)
safe_outputs Resolved temporary ID references in patch content
safe_outputs Applying patch...
safe_outputs + [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/66693")]
Broken run (bundle path)
safe_outputs Bundle file path: /tmp/gh-aw/aw-quarantine-tests-2026-05-17.bundle
safe_outputs Applying changes from bundle: /tmp/gh-aw/aw-quarantine-tests-2026-05-17.bundle
safe_outputs pushSignedCommits: replaying 1 commit(s) via GraphQL createCommitOnBranch
No Resolved temporary ID references in patch content log line. The committed code contains literal [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/#aw_passkeys1")].
Root cause
The patch-based path has a substitution step that rewrites #aw_<temporary_id> references in the patch content before applying it. The bundle-based path (which fetches a git bundle, checks out the branch, and replays commits via pushSignedCommits / GraphQL createCommitOnBranch) skips this substitution entirely — it pushes the committed file contents as-is.
The bundle path appears to have been introduced or became the default path with the changes in CLI v0.72.0/v0.72.1 and AWF v0.25.41. The refactor: decouple safe-outputs checkout from event trigger context (#30071) PR may be related, as it changed the safe-outputs checkout flow and recompiled all lock files.
Suggested fix
Before pushSignedCommits replays commits from a bundle, apply the same temporary ID substitution that the patch path uses. Specifically:
- After fetching/checking out the bundle branch but before calling
pushSignedCommits, iterate over the files in each commit
- For each file, check if its content contains any registered
#aw_<id> references
- If found, rewrite the file content with the resolved values (e.g.,
#aw_passkeys1 → 66708), amend the commit, then proceed with pushSignedCommits
Alternatively, the substitution could happen inside pushSignedCommits itself, right before the createCommitOnBranch GraphQL mutation — rewrite the file addition contents in-memory before sending them to the API.
Impact
Any workflow that uses create_issue with temporary_id and references #aw_<id> in committed source code will produce PRs with unresolved placeholder strings when the bundle path is used. PR body and title substitution still works correctly — only the committed file contents are affected.
Summary
When the safe-outputs handler uses the bundle-based push path (introduced in CLI v0.72.1 / AWF v0.25.41),
#aw_temporary ID references in committed file contents are not resolved to real issue/PR numbers. The patch-based path correctly performs this substitution.Reproduction
Two workflow runs of the same workflow (
dotnet/aspnetcoredaily test quarantine) demonstrate the regression:.patchfile.bundlefileResolved temporary ID references in patch content#aw_redirect1in codeWorking run (patch path)
Broken run (bundle path)
No
Resolved temporary ID references in patch contentlog line. The committed code contains literal[QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/#aw_passkeys1")].Root cause
The patch-based path has a substitution step that rewrites
#aw_<temporary_id>references in the patch content before applying it. The bundle-based path (which fetches a git bundle, checks out the branch, and replays commits viapushSignedCommits/ GraphQLcreateCommitOnBranch) skips this substitution entirely — it pushes the committed file contents as-is.The bundle path appears to have been introduced or became the default path with the changes in CLI v0.72.0/v0.72.1 and AWF v0.25.41. The
refactor: decouple safe-outputs checkout from event trigger context (#30071)PR may be related, as it changed the safe-outputs checkout flow and recompiled all lock files.Suggested fix
Before
pushSignedCommitsreplays commits from a bundle, apply the same temporary ID substitution that the patch path uses. Specifically:pushSignedCommits, iterate over the files in each commit#aw_<id>references#aw_passkeys1→66708), amend the commit, then proceed withpushSignedCommitsAlternatively, the substitution could happen inside
pushSignedCommitsitself, right before thecreateCommitOnBranchGraphQL mutation — rewrite the file addition contents in-memory before sending them to the API.Impact
Any workflow that uses
create_issuewithtemporary_idand references#aw_<id>in committed source code will produce PRs with unresolved placeholder strings when the bundle path is used. PR body and title substitution still works correctly — only the committed file contents are affected.