Twinned from https://github.com/cfsh/ninefold/issues/577 by tools/beads/import_github.py's reconcile pass.
Hit live while merging #567, which had #573 stacked on it. The merge was correctly refused and nothing landed — but it cannot succeed at all until this is worked around, and it will hit every stacked merge, which CLAUDE.md actively encourages ("stack branches where files overlap").
merge_pr.py retargets child PRs to main before merging the parent. That step failed:
``` presubmit PASSED against head 57de96e retargeting child PR #573 -> main refuse: a GitHub call failed, so the merge cannot be gated safely. command failed (exit 1): gh pr edit 573 -R cfsh/ninefold --base main GraphQL: Projects (classic) is being deprecated in favor of the new Projects experience, see: https://github.blog/changelog/2024-05-23-sunset-notice-projects-classic/ (repository.pullRequest.projectCards) ```
Nothing to do with the branch. gh pr edit unconditionally queries repository.pullRequest.projectCards as part of its pre-edit fetch, and GitHub has now sunset that field, so the whole call exits 1 before it ever attempts the retarget.
gh version 2.63.2 (2024-12-05) on the WSL office box. Any gh old enough to still request projectCards is affected, so it is likely broken on the sandbox box too — worth checking there before assuming this is office-box-only.
⚠️ The refusal itself is correct and should not be softened. "A GitHub call failed, so the merge cannot be gated safely" is exactly right: a half-applied stack retarget followed by a merge would leave #573 pointing at a deleted branch. The bug is the call, not the guard.
The REST endpoint does not touch projectCards:
```bash gh api -X PATCH repos/cfsh/ninefold/pulls/573 -f base=main --jq .base.ref ```
Retarget the child by hand, then re-run merge_pr.py <parent> — it finds the child already on main and skips the failing step.
Replace the gh pr edit … --base call in the retarget path with gh api -X PATCH repos/{owner}/{repo}/pulls/{n} -f base=…. Narrow and mechanical, and nflib.gh is the right home for it.
Worth auditing the tier for the same shape while in there: any gh pr edit is exposed. gh pr edit <n> --add-reviewer aedanpope is in CLAUDE.md as the documented way to re-request review after CHANGES_REQUESTED, and in this session's poll-cron prompt — if that call is broken by the same deprecation, sessions are silently failing to resurface PRs after addressing feedback. I have not tested that one; it is a different flag on the same broken command, so it should be checked rather than assumed.
Upgrading gh would also fix it, but pinning the tier to a gh floor is a machine-provisioning answer to a one-line code problem, and the REST call is version-proof either way.
Unclaimed.
None.
No comments.