{"record":{"id":"5a28c1a762385de0","repo":"Yeachan-Heo/oh-my-codex","slug":"scale-down-cleanup-debt-invalid-team-state-root","errorCode":null,"errorMessage":"scale_down_cleanup_debt_invalid_team_state_root:${worker.name}","messagePattern":"scale_down_cleanup_debt_invalid_team_state_root:(.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/team/scaling.ts","lineNumber":1582,"sourceCode":"  const repoRootResult = spawnSync('git', ['rev-parse', '--show-toplevel'], {\n    cwd: leaderCwd,\n    encoding: 'utf-8',\n    windowsHide: true,\n  });\n  const reportedRepoRoot = (repoRootResult.stdout || '').trim();\n  if (repoRootResult.status === 0 && reportedRepoRoot) {\n    repoRoot = await realpath(resolve(reportedRepoRoot));\n  }\n  const canonicalTeamStateRoot = await realpath(resolve(teamStateRoot));\n  const expectedWorkerRoot = join(canonicalTeamStateRoot, 'team', teamName, 'workers');\n\n  for (const worker of workers) {\n    const expectedWorkerDirectory = join(expectedWorkerRoot, worker.name);\n    await assertExistingPathParentContained(expectedWorkerDirectory, canonicalTeamStateRoot);\n    if (worker.team_state_root !== undefined\n      && (!isAbsolute(worker.team_state_root) || worker.team_state_root !== resolve(worker.team_state_root)\n        || resolve(worker.team_state_root) !== canonicalTeamStateRoot)) {\n      throw new Error(`scale_down_cleanup_debt_invalid_team_state_root:${worker.name}`);\n    }\n    if (worker.worktree_path === undefined) {\n      if (worker.worktree_repo_root !== undefined || worker.worktree_branch !== undefined\n        || worker.worktree_detached !== undefined || worker.worktree_created !== undefined) {\n        throw new Error(`scale_down_cleanup_debt_invalid_worktree_metadata:${worker.name}`);\n      }\n      continue;\n    }\n\n    const expectedWorktreePath = join(repoRoot, '.omx', 'team', teamName, 'worktrees', worker.name);\n    if (!isAbsolute(worker.worktree_path) || worker.worktree_path !== resolve(worker.worktree_path)\n      || resolve(worker.worktree_path) !== expectedWorktreePath\n      || (worker.worktree_repo_root !== undefined && (\n        !isAbsolute(worker.worktree_repo_root)\n        || worker.worktree_repo_root !== resolve(worker.worktree_repo_root)\n        || resolve(worker.worktree_repo_root) !== repoRoot\n      ))\n      || (worker.worktree_detached !== undefined && typeof worker.worktree_detached !== 'boolean')","sourceCodeStart":1564,"sourceCodeEnd":1600,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/team/scaling.ts#L1564-L1600","documentation":"A worker record's team_state_root fails validation: it must be an absolute, already-resolved path exactly equal to the canonical team state root. The message embeds the worker name.","triggerScenarios":"validateScaleDownCleanupResources sees worker.team_state_root defined but non-absolute, non-normalized, or resolving to a different directory than the canonical root.","commonSituations":"Team state moved or the config was hand-edited; macOS /var vs /private/var or case differences (Windows) causing resolve() mismatch; stale config from an older version storing relative roots.","solutions":["Inspect the worker record in the team config and fix team_state_root to the exact canonical absolute path","If the team state root moved, update all worker records (or regenerate the config) to the new canonical path","On macOS, watch for /var -> /private/var symlink resolution differences; store the realpath"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import { isAbsolute, resolve } from 'node:path';\nimport { realpathSync } from 'node:fs';\nfunction validTeamStateRoot(workerRoot: string | undefined, canonicalRoot: string): boolean {\n  return workerRoot === undefined\n    || (isAbsolute(workerRoot) && workerRoot === resolve(workerRoot) && resolve(workerRoot) === realpathSync(canonicalRoot));\n}","typeGuard":null,"tryCatchPattern":"catch (e) {\n  const m = /scale_down_cleanup_debt_invalid_team_state_root:(.+)$/.exec(String((e as Error).message));\n  if (m) { await fixWorkerRootInConfig(team, m[1]); return retryScaleDown(); }\n  throw e;\n}","preventionTips":["Store realpaths (not symlinked paths) in team config","After moving team state, migrate all worker records' team_state_root"],"tags":["team","scale-down","config","validation","paths"],"backgroundTag":"config-validation-failed","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}