{"record":{"id":"3486f426b9a46d15","repo":"Yeachan-Heo/oh-my-codex","slug":"autoresearch-worktree-requires-named-mode","errorCode":"autoresearch_worktree_requires_named_mode","errorMessage":"autoresearch_worktree_requires_named_mode","messagePattern":"autoresearch_worktree_requires_named_mode","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/team/worktree.ts","lineNumber":236,"sourceCode":"  }\n\n  return `${input.mode.name}/${workerName}`;\n}\n\nfunction resolveWorktreePath(input: WorktreePlanInput, repoRoot: string): string {\n  const parent = dirname(repoRoot);\n  const bucket = `${basename(repoRoot)}.omx-worktrees`;\n\n  if (input.scope === 'launch') {\n    if (!input.mode.enabled || input.mode.detached) {\n      return join(parent, bucket, 'launch-detached');\n    }\n    return join(parent, bucket, `launch-${sanitizePathToken(input.mode.name)}`);\n  }\n\n  if (input.scope === 'autoresearch') {\n    if (!input.mode.enabled || input.mode.detached) {\n      throw new Error('autoresearch_worktree_requires_named_mode');\n    }\n    const runTag = sanitizePathToken(input.worktreeTag || 'run');\n    return join(repoRoot, '.omx', 'worktrees', `autoresearch-${sanitizePathToken(input.mode.name)}-${runTag}`);\n  }\n\n  const teamName = sanitizePathToken(input.teamName || 'team');\n  const workerName = sanitizePathToken(input.workerName || 'worker');\n  return join(repoRoot, '.omx', 'team', teamName, 'worktrees', workerName);\n}\n\nfunction findWorktreeByPath(entries: GitWorktreeEntry[], worktreePath: string): GitWorktreeEntry | null {\n  const resolved = resolve(worktreePath);\n  return entries.find((entry) => resolve(entry.path) === resolved) || null;\n}\n\nfunction hasBranchInUse(entries: GitWorktreeEntry[], branchName: string, worktreePath: string): boolean {\n  const expectedRef = `refs/heads/${branchName}`;\n  const resolvedPath = resolve(worktreePath);","sourceCodeStart":218,"sourceCodeEnd":254,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/team/worktree.ts#L218-L254","documentation":"Thrown when planning an autoresearch-scoped worktree path while the mode is disabled or detached. Autoresearch worktrees are named after the mode (`autoresearch-<mode>-<runTag>`), so a named, attached mode is mandatory in that scope.","triggerScenarios":"Calling planWorktreeTarget with scope 'autoresearch' and mode.enabled false, or mode.enabled true with mode.detached true.","commonSituations":"Config built dynamically where the mode block ends up `{ enabled: false, name: 'x' }` for autoresearch scope; reusing a detached-mode config for the autoresearch scope; typos in mode flags causing detached to default true.","solutions":["Set mode = { enabled: true, detached: false, name: <non-empty> } when scope is 'autoresearch'","Audit the code that builds WorktreePlanInput and assert the scope/mode invariants before calling the planner","If you actually want a detached worktree, use a scope that supports it (team/launch path) instead of 'autoresearch'"],"exampleFix":"// before\nplanWorktreeTarget({ scope: 'autoresearch', mode: { enabled: false, name: 'eval' }, ... });\n\n// after\nplanWorktreeTarget({ scope: 'autoresearch', mode: { enabled: true, detached: false, name: 'eval' }, ... });","handlingStrategy":"validation","validationCode":"function isValidAutoresearchMode(mode: { enabled?: boolean; detached?: boolean; name?: string }): boolean {\n  return mode.enabled === true && mode.detached !== true && !!mode.name?.trim();\n}","typeGuard":"function isNamedAttachedMode(m: unknown): m is { enabled: true; detached: false; name: string } {\n  return !!m && typeof m === 'object' && (m as any).enabled === true && (m as any).detached !== true && typeof (m as any).name === 'string' && (m as any).name.length > 0;\n}","tryCatchPattern":"catch (e) { if (e instanceof Error && e.message === 'autoresearch_worktree_requires_named_mode') { /* fix mode config or switch scope */ } else throw e; }","preventionTips":["Centralize worktree-plan config construction and assert scope-specific invariants","Add schema validation (zod etc.) over mode blocks before planning","Cover autoresearch scope in config unit tests"],"tags":["worktree","validation","mode-config","autoresearch"],"backgroundTag":"invalid-configuration-value","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}