{"record":{"id":"8db4195033087dd9","repo":"Yeachan-Heo/oh-my-codex","slug":"result-stderr-trim-git-args-join","errorCode":null,"errorMessage":"(result.stderr || '').trim() || `git ${args.join(' ')} failed`","messagePattern":"\\(result\\.stderr \\|\\| ''\\)\\.trim\\(\\) \\|\\| `git (.+?) failed`","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/autoresearch/runtime.ts","lineNumber":231,"sourceCode":"  await symlink(sourceNodeModules, targetNodeModules, process.platform === 'win32' ? 'junction' : 'dir');\n}\n\nfunction readGitShortHead(worktreePath: string): string {\n  return readGit(worktreePath, ['rev-parse', '--short=7', 'HEAD']);\n}\n\nfunction readGitFullHead(worktreePath: string): string {\n  return readGit(worktreePath, ['rev-parse', 'HEAD']);\n}\n\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 {","sourceCodeStart":213,"sourceCodeEnd":249,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/autoresearch/runtime.ts#L213-L249","documentation":"requireGitSuccess runs a synchronous git subprocess and throws the trimmed stderr (or 'git <args> failed') when the exit status is non-zero. It is used for mutating operations such as resetToLastKeptCommit.","triggerScenarios":"Calling resetToLastKeptCommit (or other flows using requireGitSuccess) where the underlying git reset/checkout fails: unknown commit, dirty index conflicts, missing worktree metadata (.git file pointing to a deleted main repo), or git refusing to operate.","commonSituations":"The autoresearch worktree's backing repository was deleted or moved, the kept commit was garbage-collected, concurrent processes mutating the same worktree, or filesystem permission errors in the worktree.","solutions":["Run the exact printed git command inside the worktree path to reproduce and read the error","Verify the target commit still exists (git cat-file -t <sha>) and was not garbage-collected","Confirm the worktree's .git link still points to an existing main repository","Ensure no other process is concurrently running git in the same worktree"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import { spawnSync } from 'node:child_process';\nfunction commitExists(worktreePath: string, sha: string): boolean {\n  return spawnSync('git', ['cat-file', '-t', sha], { cwd: worktreePath }).status === 0;\n}","typeGuard":null,"tryCatchPattern":"try { await resetToLastKeptCommit(worktreePath, sha); }\ncatch (e) { if (e instanceof Error && /git .* failed/.test(e.message)) { /* run the printed git command manually to diagnose */ } throw e; }","preventionTips":["Verify target commits exist before reset operations","Keep the main repository alive as long as linked worktrees reference it","Serialize git mutations per worktree"],"tags":["git","subprocess","reset","worktree"],"backgroundTag":"git-command-failed","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}