fix(FN-7224): clear workflow pins on retry
Fusion-Task-Id: FN-7224
This commit is contained in:
7
.changeset/fn-7224-retry-clears-workflow-pins.md
Normal file
7
.changeset/fn-7224-retry-clears-workflow-pins.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"@runfusion/fusion": patch
|
||||
---
|
||||
|
||||
summary: Make dashboard retry clear stale workflow step pins before re-execution.
|
||||
category: fix
|
||||
dev: Clears persisted workflow step instances on manual execution retry so parse-steps can repin the current plan.
|
||||
@@ -216,6 +216,7 @@ function createMockStore(overrides: Partial<TaskStore> = {}): TaskStore {
|
||||
getWorkflowStep: vi.fn(),
|
||||
updateWorkflowStep: vi.fn(),
|
||||
deleteWorkflowStep: vi.fn(),
|
||||
clearWorkflowRunStepInstances: vi.fn(),
|
||||
getMissionStore: vi.fn().mockReturnValue({
|
||||
listMissions: vi.fn().mockReturnValue([]),
|
||||
createMission: vi.fn(),
|
||||
@@ -808,6 +809,7 @@ describe("POST /tasks/:id/retry", () => {
|
||||
baseCommitSha: null,
|
||||
...buildManualRetryResetPatch({ resetMergeRetries: true }),
|
||||
});
|
||||
expect(store.clearWorkflowRunStepInstances).toHaveBeenCalledWith("KB-001");
|
||||
expect(store.moveTask).toHaveBeenCalledWith("KB-001", "todo");
|
||||
});
|
||||
|
||||
@@ -896,6 +898,7 @@ describe("POST /tasks/:id/retry", () => {
|
||||
error: null,
|
||||
...buildManualRetryResetPatch(),
|
||||
});
|
||||
expect(store.clearWorkflowRunStepInstances).toHaveBeenCalledWith("KB-001");
|
||||
expect(store.moveTask).toHaveBeenCalledWith("KB-001", "todo", { preserveProgress: true });
|
||||
expect(store.logEntry).toHaveBeenCalledWith(
|
||||
"KB-001",
|
||||
@@ -927,6 +930,7 @@ describe("POST /tasks/:id/retry", () => {
|
||||
error: null,
|
||||
...buildManualRetryResetPatch(),
|
||||
});
|
||||
expect(store.clearWorkflowRunStepInstances).toHaveBeenCalledWith("KB-001");
|
||||
expect(store.moveTask).toHaveBeenCalledWith("KB-001", "todo", { preserveProgress: true });
|
||||
expect(store.logEntry).toHaveBeenCalledWith(
|
||||
"KB-001",
|
||||
@@ -963,6 +967,7 @@ describe("POST /tasks/:id/retry", () => {
|
||||
error: null,
|
||||
...buildManualRetryResetPatch(),
|
||||
});
|
||||
expect(store.clearWorkflowRunStepInstances).toHaveBeenCalledWith("KB-001");
|
||||
expect(store.moveTask).toHaveBeenCalledWith("KB-001", "todo", { preserveProgress: true });
|
||||
expect(store.logEntry).toHaveBeenCalledWith(
|
||||
"KB-001",
|
||||
|
||||
@@ -1683,6 +1683,11 @@ export function registerTaskWorkflowRoutes(ctx: ApiRoutesContext, deps: TaskWork
|
||||
// and merge failures (all steps done).
|
||||
if (isInReviewRetry) {
|
||||
if (isExecutionFailureInReview) {
|
||||
/*
|
||||
FNXC:WorkflowRetry 2026-06-29-02:18:
|
||||
Dashboard retry for an in-review execution failure re-enters the workflow graph from parse/execution, so it must clear persisted foreach step-instance pins. Otherwise a stale pin from the failed run makes the retry hit the same parse pin-mismatch immediately.
|
||||
*/
|
||||
clearRebuiltSpecWorkflowPins(scopedStore, req.params.id);
|
||||
await scopedStore.updateTask(req.params.id, {
|
||||
status: null,
|
||||
error: null,
|
||||
@@ -1734,6 +1739,12 @@ export function registerTaskWorkflowRoutes(ctx: ApiRoutesContext, deps: TaskWork
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
FNXC:WorkflowRetry 2026-06-29-02:18:
|
||||
Non-planning manual retry is also a fresh execution boundary. Clear graph step-instance rows before moving back to todo so parse-steps can repin the current PROMPT.md instead of inheriting failed foreach state.
|
||||
*/
|
||||
clearRebuiltSpecWorkflowPins(scopedStore, req.params.id);
|
||||
|
||||
// Reset steps if the branch has no unique commits (work was lost with worktree)
|
||||
const completedSteps = task.steps.filter(
|
||||
(s: { status: string }) => s.status === "done" || s.status === "in-progress",
|
||||
|
||||
Reference in New Issue
Block a user