{"record":{"id":"91f23fce8a293672","repo":"Yeachan-Heo/oh-my-codex","slug":"canonical-scale-down-task-verification-failed-ta","errorCode":null,"errorMessage":"canonical_scale_down_task_verification_failed:${task.id}","messagePattern":"canonical_scale_down_task_verification_failed:(.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/team/scaling.ts","lineNumber":2174,"sourceCode":"              worktree_repo_root: worker.worktree_repo_root,\n              worktree_branch: worker.worktree_branch,\n              worktree_detached: worker.worktree_detached,\n              worktree_created: worker.worktree_created,\n              team_state_root: worker.team_state_root,\n            })),\n          };\n          await writeAtomic(cleanupDebtPath, JSON.stringify(cleanupDebtBase, null, 2));\n          await commitTeamMembershipTaskTransaction(sanitized, leaderCwd, membershipTransaction);\n          const committed = await readTeamConfig(sanitized, leaderCwd);\n          if (!committed || committed.workers.some((worker) => removableWorkerNames.has(worker.name))) {\n            throw new Error('canonical_scale_down_config_verification_failed');\n          }\n          config.workers = committed.workers;\n          config.worker_count = committed.worker_count;\n          for (const task of reconciledTasks) {\n            const reconciled = await readTask(sanitized, task.id, leaderCwd);\n            if (reconciled && (removableWorkerNames.has(reconciled.owner ?? '') || removableWorkerNames.has(reconciled.claim?.owner ?? ''))) {\n              throw new Error(`canonical_scale_down_task_verification_failed:${task.id}`);\n            }\n          }\n\n          // PID-less rollback records are cleanup debt, not effect authority. A\n          // fresh gone proof may resolve one, but a live or unavailable proof\n          // must remain debt rather than letting teardown adopt its current PID.\n          const pinnedPaneWorkers = removableWorkers.filter((worker): worker is WorkerInfo & {\n            pane_id: string;\n            pid: number;\n          } => (\n            typeof worker.pane_id === 'string'\n            && /^%\\d+$/.test(worker.pane_id)\n            && typeof worker.pid === 'number'\n            && Number.isSafeInteger(worker.pid)\n            && worker.pid > 0\n          ));\n          const unpinnedPaneWorkers = removableWorkers.filter((worker) => (\n            typeof worker.pane_id === 'string'","sourceCodeStart":2156,"sourceCodeEnd":2192,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/team/scaling.ts#L2156-L2192","documentation":"After scale-down, a reconciled task still references a removed worker as owner or claim owner, meaning task reassignment did not take effect. Message embeds the task.id.","triggerScenarios":"scaleDown re-reads each reconciled task; readTask returns a task whose owner or claim.owner is in removableWorkerNames.","commonSituations":"Concurrent worker writing/claiming its task during teardown; task file rewritten between reassignment and verification; transaction journal not applied to task files.","solutions":["Inspect the reported task file and manually clear/reassign the owner and claim fields","Ensure the removed workers' processes are terminated before scaling down","Re-run scaleDown to reconcile remaining task ownership"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"catch (e) {\n  const m = /canonical_scale_down_task_verification_failed:(.+)$/.exec(String((e as Error).message));\n  if (m) { await reassignTaskOwner(team, m[1]); return retryScaleDown(); }\n  throw e;\n}","preventionTips":["Terminate worker processes before scale-down so they cannot re-claim tasks","Re-run scale-down to let reconciliation finish task reassignment"],"tags":["team","scale-down","tasks","ownership","verification"],"backgroundTag":"orphaned-resource-after-rollback","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}