{"record":{"id":"b1d21bdd32dbd856","repo":"Yeachan-Heo/oh-my-codex","slug":"canonical-scale-up-rollback-worker-verification-fa","errorCode":null,"errorMessage":"canonical_scale_up_rollback_worker_verification_failed:${workerName}","messagePattern":"canonical_scale_up_rollback_worker_verification_failed:(.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/team/scaling.ts","lineNumber":990,"sourceCode":"        ...(context.workerName && !unresolvedWorkerNames.has(context.workerName) ? [context.workerName] : []),\n      ]);\n      try {\n        for (const taskId of createdTaskIds) {\n          const task = await readTask(sanitized, taskId, leaderCwd);\n          if (task && unresolvedWorkerNames.has(task.owner ?? '')) continue;\n          await rm(join(teamStateRoot, 'team', sanitized, 'tasks', `task-${taskId}.json`), { force: true });\n        }\n        await Promise.all([...cleanupWorkerNames].map(async (workerName) => {\n          await rm(join(teamStateRoot, 'team', sanitized, 'workers', workerName), { recursive: true, force: true });\n        }));\n        for (const taskId of createdTaskIds) {\n          const task = await readTask(sanitized, taskId, leaderCwd);\n          if (task && unresolvedWorkerNames.has(task.owner ?? '')) continue;\n          if (task) throw new Error(`canonical_scale_up_rollback_task_verification_failed:${taskId}`);\n        }\n        for (const workerName of cleanupWorkerNames) {\n          if (existsSync(join(teamStateRoot, 'team', sanitized, 'workers', workerName))) {\n            throw new Error(`canonical_scale_up_rollback_worker_verification_failed:${workerName}`);\n          }\n        }\n      } catch (rollbackError) {\n        cleanupDebt.push(`canonical_cleanup_failed:${String(rollbackError)}`);\n      }\n\n      try {\n        const contextWorkerName = context.worker?.name ?? context.workerName;\n        const contextWorktreePath = context.worker?.worktree_path ?? context.worktreePath;\n        if (contextWorkerName && contextWorktreePath && !unresolvedWorkerNames.has(contextWorkerName)) {\n          await removeWorkerWorktreeRootAgentsFile(sanitized, contextWorkerName, teamStateRoot, contextWorktreePath);\n        }\n        const unresolvedWorktreePaths = new Set(rollbackWorkers\n          .filter((worker) => unresolvedWorkerNames.has(worker.name) && typeof worker.worktree_path === 'string')\n          .map((worker) => resolve(worker.worktree_path as string)));\n        await rollbackProvisionedWorktrees(provisionedWorktrees.filter((worktree) => !unresolvedWorktreePaths.has(resolve(worktree.worktreePath))));\n        await Promise.all([...preparedWorkerDirectoryOwner.entries()]\n          .filter(([, workerName]) => !unresolvedWorkerNames.has(workerName))","sourceCodeStart":972,"sourceCodeEnd":1008,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/team/scaling.ts#L972-L1008","documentation":"During scale-up rollback, a worker directory that should have been deleted still exists under team state workers/. The message embeds the workerName whose directory survived cleanup.","triggerScenarios":"scaleUp rollback removes worker directories with rm recursive force, then existsSync still finds the worker directory path present.","commonSituations":"Filesystem race where a worker process recreates its directory; permission issues blocking deletion; Windows/macOS file locking holding the directory.","solutions":["Manually remove the reported worker directory under team state workers/ and retry scaleUp","Ensure the worker process/pane for that worker is terminated before scaling again","Check filesystem permissions on the team state root"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"import { existsSync, rmSync } from 'node:fs';\nimport { join } from 'node:path';\n// before retrying, confirm worker dirs are gone\nfunction workerDirsClean(stateRoot: string, team: string, workers: string[]): boolean {\n  return workers.every((w) => !existsSync(join(stateRoot, 'team', team, 'workers', w)));\n}","typeGuard":null,"tryCatchPattern":"catch (e) {\n  const m = /canonical_scale_up_rollback_worker_verification_failed:(.+)$/.exec(String((e as Error).message));\n  if (m) { rmSync(join(stateRoot,'team',team,'workers',m[1]), { recursive: true, force: true }); return retryScaleUp(); }\n  throw e;\n}","preventionTips":["Terminate worker panes/processes before scaling","Check directory permissions on the team state root"],"tags":["team","scaling","rollback","filesystem","cleanup"],"backgroundTag":"orphaned-resource-after-rollback","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}