{"record":{"id":"5e048a1706f939ab","repo":"Yeachan-Heo/oh-my-codex","slug":"shutdown-config-missing-config-name","errorCode":null,"errorMessage":"shutdown_config_missing:${config.name}","messagePattern":"shutdown_config_missing:(.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/team/runtime.ts","lineNumber":345,"sourceCode":"  teamName: string,\n  cwd: string,\n  leaderSessionId?: string,\n): Promise<void> {\n  await syncExactTeamModeStateOnShutdown(teamName, cwd);\n  const normalizedLeaderSessionId = typeof leaderSessionId === 'string' ? leaderSessionId.trim() : '';\n  if (normalizedLeaderSessionId) {\n    await syncExactTeamModeStateOnShutdown(teamName, cwd, normalizedLeaderSessionId);\n  }\n}\n\nasync function mutateShutdownConfig(\n  config: TeamConfig,\n  cwd: string,\n  mutate: (current: TeamConfig) => void,\n): Promise<TeamConfig> {\n  return await withTeamTaskMembershipBarrier(config.name, cwd, async () => {\n    const current = await readTeamConfig(config.name, cwd);\n    if (!current) throw new Error(`shutdown_config_missing:${config.name}`);\n    const baseGeneration = current.config_generation ?? 0;\n    const teamRoot = join(current.team_state_root ?? resolveCanonicalTeamStateRoot(cwd), 'team', current.name);\n    const [currentConfigBytes, currentManifestBytes] = await Promise.all([\n      readFile(join(teamRoot, 'config.json'), 'utf8'),\n      existsSync(join(teamRoot, 'manifest.v2.json')) ? readFile(join(teamRoot, 'manifest.v2.json'), 'utf8') : null,\n    ]);\n    mutate(current);\n    const currentManifest = currentManifestBytes === null ? null : JSON.parse(currentManifestBytes) as Record<string, unknown>;\n    await commitTeamMembershipTaskTransaction(current.name, cwd, {\n      baseGeneration,\n      tasks: [],\n      config: { oldBytes: currentConfigBytes, newBytes: JSON.stringify(current, null, 2) },\n      manifest: {\n        oldBytes: currentManifestBytes,\n        newBytes: currentManifest === null ? null : JSON.stringify({\n          ...currentManifest,\n          hud_pane_id: current.hud_pane_id,\n          hud_pane_pid: current.hud_pane_pid,","sourceCodeStart":327,"sourceCodeEnd":363,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/team/runtime.ts#L327-L363","documentation":"mutateShutdownConfig re-reads the team config from disk inside the barrier before mutating it; if readTeamConfig returns null the team's config.json no longer exists (or is unreadable/invalid), so there is nothing to mutate and the shutdown sequence aborts. The name suffix identifies which team was being mutated.","triggerScenarios":"Calling shutdownTeam or any path through mutateShutdownConfig after the team state directory was deleted, moved, or its config.json corrupted.","commonSituations":"Concurrent shutdowns racing to delete state, manual rm of the team state root, an external cleanup job, or cwd mismatch resolving a different state root.","solutions":["Run `omx team status <name>` to confirm the team state exists in the expected state root","If state was intentionally removed, treat this as already-shutdown and ignore the error","Ensure the cwd passed matches the one the team was started in so the canonical state root resolves identically"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"const exists = await readTeamConfig(name, cwd);\nif (!exists) { /* treat as already shut down; skip mutation */ }","typeGuard":null,"tryCatchPattern":"try { await shutdownTeam(config, cwd); } catch (e) { if (e instanceof Error && e.message.startsWith('shutdown_config_missing:') && !await readTeamConfig(config.name, cwd)) { return; /* already gone */ } throw e; }","preventionTips":["Check team status before shutdown","Always pass the same cwd used at start","Avoid manually deleting state directories mid-operation"],"tags":["team-runtime","shutdown","missing-state-file","concurrency"],"backgroundTag":"missing-state-file","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}