watch_pull_request refuses an open PR as merged when a recreated repo reuses its number#33407
What happened
Agents called watch_pull_request on PRs that were open on GitHub. The tool answered "The pull request is merged, so there is nothing to watch." Agents then fell back to polling by hand. This happened 4 times in 2 days, in 2 repos.
Diagnosis
Both repos were deleted and recreated under the same name, so GitHub restarted PR numbering. Each affected thread still held links from the old repo. A link is keyed by host, repository and number, so the old merged snapshot now stands for a different, open PR.
setWatchingrefuses from the stored snapshot without asking the host:if (watching && before?.snapshot?.state === "merged")inapps/server/src/mcp/toolkits/pullRequests/handlers.ts:278.PullRequestSyncReactortreats a merged snapshot withmergedAtas final and never reads it again (isDue,PullRequestSyncReactor.ts:356-361). The wrong snapshot never heals.link_pull_requestreturns early when the link exists (Orchestrator.ts:3762), so linking again does not refresh it either.PullRequestWatchReactorends a watch on a storedmergedsnapshot without a read (endsWithoutRead,PullRequestWatchReactor.ts:410), so dropping the refusal alone would not help.
The stored snapshot for java-web #79 has the title and mergedAt (2026-10-27) of the old repo's #79. The current #79 was opened 2026-11-09 and is open. The thread also keeps links to old #81 to #101, which now return 404 on every sync (74 GitHubApiNotFoundError in one day of traces).
#15741 fixed the same refusal for closed, on the grounds that a merged PR cannot reopen. A recreated repo breaks that assumption. main still has the check.
Steps to reproduce
- In a thread, link PR #N of
owner/repoand let it merge. Wait for the sync to storestate: merged. - Delete
owner/repoon GitHub and create a new repo with the same name. - Open new PRs in the new repo until one gets number #N.
- From the same thread, call
watch_pull_requestforowner/repo#N.
Expected: T3 reads the host and watches the open PR. Actual: "The pull request is merged, so there is nothing to watch."
Version
0.1.7 (server). Same check on main at time of filing.
Environment
Linux arm64, Node 26.12.1, server run as a background service, Claude agent provider, GitHub repos.
Evidence
| 1 | watch_pull_request {"repository":"Project516/java-web","number":79} |
| 2 | -> The pull request is merged, so there is nothing to watch. |
| 3 | |
| 4 | GitHub: #79 OPEN, createdAt 2026-11-09T00:39:06Z, mergedAt null |
| 5 | Stored snapshot: state merged, mergedAt 2026-10-27T23:43:18Z, title "Run StringBuilder.append(String) and toString as intrinsics" |
| 6 | Repo createdAt: 2026-10-31T20:12:24Z |
| 7 | |
| 8 | Same for Project516/frc-dev-wasm #8 and #10 (repo recreated 2026-11-08T18:26:59Z; stored snapshots are October PRs). |
Related issues
#15744 (closed, fixed by #15741): same refusal for reopened closed PRs. Not a duplicate, since that fix kept the merged check and this case needs it.
#25160: different watch problem (ends silently on merge).
Fix applied or workaround
Call unlink_pull_request for the stale PR, then watch_pull_request. Unlink drops a non-stack link, so the watch links it again with an empty snapshot and the sync reads the host. Nothing was changed on the machine during triage.
Filed by
Claude Code, claude-opus-5-5, via t3 triage.