fix(heartbeat): prevent false auto-block after successful continuation retry#4440
fix(heartbeat): prevent false auto-block after successful continuation retry#4440DeadlySilent wants to merge 5 commits intopaperclipai:masterfrom
Conversation
Greptile SummaryThis PR fixes a false auto-block regression in heartbeat reconciliation by skipping the continuation escalation path when the latest run already succeeded, and bundles related improvements: stale execution lock repair in
Confidence Score: 4/5Not safe to merge until the constraint name mismatch in The heartbeat guard and test coverage are correct, but the new server/src/services/routines.ts — Important Files Changed
Prompt To Fix All With AIThis is a comment left during a code review.
Path: server/src/services/routines.ts
Line: 63-79
Comment:
**New constraint name not handled**
`isOpenRoutineExecutionConflict` only matches `"issues_open_routine_execution_uq"`, but the migration added in this PR introduces a *second* partial unique index named `"issues_open_routine_origin_uq"` (on `company_id, origin_kind, origin_id`). When `issueSvc.create` violates the new index, Postgres returns `code: "23505"` with `constraint_name: "issues_open_routine_origin_uq"`, which won't match either branch of the check, so `!isOpenExecutionConflict` is `true` and the error is re-thrown unhandled — the run is marked `failed` and the recovery paths are never reached.
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: server/src/routes/issues.ts
Line: 1348-1350
Comment:
**Double `assertCompanyAccess` call**
`assertCanCreateIssues` already calls `assertCompanyAccess(req, companyId)` internally (line 405), so the call on line 1348 is redundant. This is harmless today but creates a maintenance hazard if the access logic ever differs between the two callsites.
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: server/src/routes/issues.ts
Line: 397-413
Comment:
**`user` actor type falls through to `unauthorized()`**
`assertCanCreateIssues` only explicitly handles `board` and `agent` actors; any other `req.actor.type` (e.g. a `user` actor, if that type exists in the system) hits the terminal `throw unauthorized()`. If `user` actors are ever expected to call `POST /companies/:companyId/issues`, they would receive a 401 instead of a 403. Please confirm this fall-through is intentional and all valid actor types are covered.
How can I resolve this? If you propose a fix, please make it concise.Reviews (1): Last reviewed commit: "fix(heartbeat): skip continuation auto-b..." | Re-trigger Greptile |
Fix P1 review comment on PR paperclipai#4440: - Update isOpenRoutineExecutionConflict to also handle the new issues_open_routine_origin_uq constraint added in migration 0057 - Without this fix, violation of the new constraint would be re-thrown unhandled, causing runs to be marked failed instead of reaching the recovery path Also remove redundant assertCompanyAccess call (P2): - assertCanCreateIssues already calls assertCompanyAccess internally - The call at line 1350 was redundant Co-Authored-By: Paperclip <noreply@paperclip.ing>
Fix P1 review comment on PR paperclipai#4440: - Update isOpenRoutineExecutionConflict to also handle the new issues_open_routine_origin_uq constraint added in migration 0057 - Without this fix, violation of the new constraint would be re-thrown unhandled, causing runs to be marked failed instead of reaching the recovery path Also remove redundant assertCompanyAccess call (P2): - assertCanCreateIssues already calls assertCompanyAccess internally - The call at line 1350 was redundant Co-Authored-By: Paperclip <noreply@paperclip.ing>
Summary
in_progressissues when the latest continuation retry already succeededWhy
reconcileStrandedAssignedIssues()could escalate toblockedbased only on a previousretryReason=issue_continuation_needed, even when the latest run had already succeeded. This caused false-positive auto-block churn in live issue lanes.Changes
server/src/services/heartbeat.tssucceeded, skip continuation escalation pathserver/src/__tests__/heartbeat-process-recovery.test.tsdoes not auto-block in-progress work when the latest continuation retry already succeededValidation
pnpm --filter server test -- heartbeat-process-recovery.test.ts(pass)Operational context
This patch was applied in hotfix runtime and validated against recurrence conditions observed in IOS lane (IOS-601).