{"record":{"id":"71e071bc9e597753","repo":"Yeachan-Heo/oh-my-codex","slug":"result-stderr-trim-git-status-failed","errorCode":null,"errorMessage":"(result.stderr || '').trim() || `git status failed for ${worktreePath}`","messagePattern":"\\(result\\.stderr \\|\\| ''\\)\\.trim\\(\\) \\|\\| `git status failed for (.+?)`","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/autoresearch/runtime.ts","lineNumber":241,"sourceCode":"\nfunction requireGitSuccess(worktreePath: string, args: string[]): void {\n  const result = spawnSync('git', args, {\n    cwd: worktreePath,\n    encoding: 'utf-8',\n      windowsHide: true,\n    });\n  if (result.status === 0) return;\n  throw new Error((result.stderr || '').trim() || `git ${args.join(' ')} failed`);\n}\n\nfunction gitStatusLines(worktreePath: string): string[] {\n  const result = spawnSync('git', ['status', '--porcelain', '--untracked-files=all'], {\n    cwd: worktreePath,\n    encoding: 'utf-8',\n      windowsHide: true,\n    });\n  if (result.status !== 0) {\n    throw new Error((result.stderr || '').trim() || `git status failed for ${worktreePath}`);\n  }\n  return (result.stdout || '')\n    .split(/\\r?\\n/)\n    .map((line) => line.trimEnd())\n    .filter(Boolean);\n}\n\nfunction isAllowedRuntimeDirtyLine(line: string): boolean {\n  const trimmed = line.trim();\n  if (trimmed.length < 4) return false;\n  const path = trimmed.slice(3).trim();\n  return trimmed.startsWith('?? ') && AUTORESEARCH_WORKTREE_EXCLUDES.some((exclude) => exclude.endsWith('/')\n    ? path.startsWith(exclude) || path === exclude.slice(0, -1)\n    : path === exclude);\n}\n\nexport function assertResetSafeWorktree(worktreePath: string): void {\n  const lines = gitStatusLines(worktreePath);","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/autoresearch/runtime.ts#L223-L259","documentation":"gitStatusLines runs `git status --porcelain --untracked-files=all` in the worktree and throws the stderr or a generic message when the command exits non-zero. It is the entry point for all worktree cleanliness inspection in the autoresearch runtime.","triggerScenarios":"Any call path that inspects worktree status (assertResetSafeWorktree, prepare/resume runtime) when git status fails: corrupt index file, invalid .git link in a linked worktree, or a repository owned by a different user (dubious ownership).","commonSituations":"Corrupt .git/index after a crash, worktrees whose main repo was removed, running as a different user than the repo owner (safe.directory issues), or CI checkouts with odd permissions.","solutions":["Run `git status --porcelain --untracked-files=all` in the printed worktreePath to see the underlying error","For 'detected dubious ownership', run `git config --global --add safe.directory <path>` or match user ownership","If the index is corrupt, delete the worktree's index file and let git rebuild it, or recreate the worktree","If the main repo of a linked worktree is gone, remove and recreate the worktree"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import { spawnSync } from 'node:child_process';\nfunction statusWorks(worktreePath: string): boolean {\n  return spawnSync('git', ['status', '--porcelain'], { cwd: worktreePath }).status === 0;\n}","typeGuard":null,"tryCatchPattern":"try { assertResetSafeWorktree(worktreePath); }\ncatch (e) { if (e instanceof Error && /git status failed/.test(e.message)) { /* run git status manually; check safe.directory and index integrity */ } throw e; }","preventionTips":["Set git safe.directory when repo and process owners differ","Avoid deleting the main repo behind linked worktrees","Keep .git/index intact; avoid killing processes mid-status"],"tags":["git","worktree","status","corruption"],"backgroundTag":"git-command-failed","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}