mirror of
https://github.com/Comfy-Org/github-workflows.git
synced 2026-11-05 00:17:37 +00:00
[PR #388] [MERGED] fix(cursor-review): retry a panel cell on Cursor's transient resource_exhausted error #387
Labels
No labels
cursor-review-catalog-drift
groom
groom
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Comfy-Org/github-workflows#387
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/Comfy-Org/github-workflows/pull/388
Author: @mattmillerai
Created: 10/9/2026
Status: ✅ Merged
Merged: 10/9/2026
Merged by: @mattmillerai
Base:
main← Head:be-19849-cursor-review-retry-resource-exhausted📝 Commits (3)
1a6a8cefix(cursor-review): retry a panel cell on Cursor's transient resource_exhausted errorc7a5eebfix(cursor-review): rewind the prompt before a retried attempt454e25efix(cursor-review): report a signal that lands while the agent's stderr drains📊 Changes
4 files changed (+576 additions, -23 deletions)
View changed files
📝
.github/cursor-review/README.md(+1 -1)📝
.github/cursor-review/stop-on-submit.py(+253 -20)📝
.github/cursor-review/tests/test_stop_on_submit.py(+308 -2)📝
.github/workflows/cursor-review.yml(+14 -0)📄 Description
ELI-5
Sometimes Cursor says "I'm too busy right now, try again" (
RetriableError: [resource_exhausted]) about 25 seconds into a review cell. Today the cell gives up straight away and the panel posts with reviewers missing. With this change the cell waits a bit and tries again, at most twice, before it gives up.What changed
stop-on-submit.py(the wrapper around each panel cell'scursor-agent) gets a retry loop:[resource_exhausted]orRetriableError. stderr passes through the wrapper and is copied on to its own stderr byte for byte, so/tmp/review-stderr.txtgets the same content as before. stdout is inherited untouched.< /tmp/prompt.txt) is rewound to its starting offset before every retry; a stdin that cannot seek rules the retry out.--retry-delays 30,90, so at most 2 retries.findings.jsonto parse as an object whose status is notokand whosefindingslist is empty.review-output-mcp.pyappends each recorded finding, so re-running a cell that already recorded some would duplicate them. Those cells, and an unreadable file, fail exactly as they do today.--retry-window 300seconds after the wrapper started (delay included). The last attempt therefore still has about 10 of the 15 minutes for a full review. If it runs past that, the step cap kills it as before.::warning::Reviewer cell <review_type>/<model>: attempt N/3 failed with Cursor's retriable error [resource_exhausted] (exit 1); retrying in 30s. The warning names only the fixed marker, never text the agent printed, and the cell label is sanitized.cursor-review.ymlRun cursor reviewpasses--retry-delays 30,90 --retry-window 300 --cell "$REVIEW_TYPE/$MODEL"(it addsREVIEW_TYPEto the step env) and has a comment explaining why. A cell that uses up its retries still endsstatus=error, andFail the leg when the cell did not submitstill turns it red.stop-on-submit.pyupdated.Judgment calls
okstatus and no recorded findings, so partial reviews are never duplicated.Provenance
.github/cursor-review/testssuite (1188 tests, Python 3.12) passes on the current head, includingtest_stop_on_submit.py(41 tests)RetryTest(real wrapper over a stub agent that reads its whole stdin): retry then success, retries used up, every attempt gets the full prompt (also when stdin starts partway in), a pipe on stdin rules the retry out, a marker on stdout isn't retried, the warning starts its own line, other errors, exit 0 and signal death not retried, submitted or partially recorded findings not re-run, retry window, signal during the backoffcheck_workflow_pins.pyandcheck_agents_md.pypass on the current head;check-org-repo-literals.sh, shellcheck and actionlint were run on earlier roundsResidual
ci-cursor-review.ymlruns on the consumer repo were re-read here. The matcher is based on the quoted log tailRetriableError: [resource_exhausted] Error. After the next cursor-review bump, check a consumer run with a Kimi (kimi-k3-high) failure for the new::warning::Reviewer cell …line and a second attempt in theRun cursor reviewlog.status=error, as the ticket allows. The model swap and counting the direct-OpenAI cell toward the gate are the separate follow-ups the ticket names.review-openai-direct) and the judge/consolidate step get no retry. Both are out of scope per the ticket.Review fixes
< /tmp/prompt.txt, and every attempt shares that one open file and its read position. The first attempt read it to the end, so a retriedcursor-agentgot an empty prompt and failed at once (No prompt provided for print mode). The retry could never save a cell. The wrapper now notes where stdin starts and moves it back there before every retry. If stdin can't be rewound (a pipe or a terminal), it doesn't retry and logs one line saying why. A workflow comment and the wiring test now pin the file redirect.::warning::always starts on its own line. When the agent's last stderr write had no trailing newline, the warning was glued onto it and the runner didn't pick it up. The wrapper now starts a new line first when needed./tmp/review-raw.txtagain, as before this PR. This replaces the "both stdout and stderr are scanned" judgment call above.🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.