Problem
If deploying harness B fails after harness A succeeds, the partial state (containing harness A's new ID) is never persisted to disk.
Flow:
HarnessDeployer.deploy() returns { success: false, state: resultState } — resultState contains harness A's ID
actions.ts:531 extracts the state into deployedHarnesses
actions.ts:541 returns early with an error — before writeDeployedState() at line 584
On next deploy attempt, the state file doesn't know harness A exists. The deployer takes the CREATE path (createHarness with clientToken: randomUUID()), producing a duplicate cloud resource. The previous harness A is orphaned.
Expected behavior
Partial state should be persisted even on failure, so the next deploy attempt can UPDATE existing harnesses rather than re-creating them.
Possible fix
Write deployed state before the early return at line 541:
if (harnessDeployError) {
// Persist partial state so successfully-created harnesses aren't orphaned
await configIO.writeDeployedState(buildDeployedState(...));
return { success: false, error: harnessDeployError };
}
Context
Found during review of #1341.
Problem
If deploying harness B fails after harness A succeeds, the partial state (containing harness A's new ID) is never persisted to disk.
Flow:
HarnessDeployer.deploy()returns{ success: false, state: resultState }—resultStatecontains harness A's IDactions.ts:531extracts the state intodeployedHarnessesactions.ts:541returns early with an error — beforewriteDeployedState()at line 584On next deploy attempt, the state file doesn't know harness A exists. The deployer takes the CREATE path (
createHarnesswithclientToken: randomUUID()), producing a duplicate cloud resource. The previous harness A is orphaned.Expected behavior
Partial state should be persisted even on failure, so the next deploy attempt can UPDATE existing harnesses rather than re-creating them.
Possible fix
Write deployed state before the early return at line 541:
Context
Found during review of #1341.