{"record":{"id":"d1f925ae667c2716","repo":"paperclipai/paperclip","slug":"failed-to-reset-local-git-index-to-head-after-work","errorCode":null,"errorMessage":"Failed to reset local git index to HEAD after workspace restore: ${detail}","messagePattern":"Failed to reset local git index to HEAD after workspace restore: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/adapter-utils/src/git-workspace-sync.ts","lineNumber":484,"sourceCode":"\nexport async function resetLocalGitIndexToHead(input: {\n  localDir: string;\n  checkWorkingTreeClean?: boolean;\n}): Promise<void> {\n  try {\n    await runLocalGit(input.localDir, [\"reset\", \"--quiet\", \"HEAD\", \"--\", \".\"], {\n      timeout: 60_000,\n      maxBuffer: 1024 * 1024,\n    });\n  } catch (error) {\n    const detail = error && typeof error === \"object\"\n      ? [\n        (error as { message?: unknown }).message,\n        (error as { stderr?: unknown }).stderr,\n        (error as { stdout?: unknown }).stdout,\n      ].filter((value): value is string => typeof value === \"string\" && value.trim().length > 0).join(\"\\n\")\n      : String(error);\n    throw new Error(`Failed to reset local git index to HEAD after workspace restore: ${detail}`);\n  }\n\n  const stagedDiff = await runLocalGit(input.localDir, [\"diff\", \"--cached\", \"--name-status\", \"HEAD\", \"--\"], {\n    timeout: 10_000,\n    maxBuffer: 1024 * 1024,\n  });\n  if (stagedDiff.stdout.trim().length > 0) {\n    throw new Error(\n      `Workspace restore left staged git index changes after reset:\\n${stagedDiff.stdout.trim()}`,\n    );\n  }\n\n  if (!input.checkWorkingTreeClean) return;\n\n  const workingTreeDiff = await runLocalGit(input.localDir, [\"diff\", \"--name-status\", \"HEAD\", \"--\"], {\n    timeout: 10_000,\n    maxBuffer: 1024 * 1024,\n  });","sourceCodeStart":466,"sourceCodeEnd":502,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/packages/adapter-utils/src/git-workspace-sync.ts#L466-L502","documentation":"Thrown by resetLocalGitIndexToHead when `git reset --quiet HEAD -- .` fails. This runs after a workspace restore to ensure the git index matches HEAD. The error detail includes the git error message, stderr, and stdout concatenated so the developer can see the underlying git failure.","triggerScenarios":"Calling resetLocalGitIndexToHead({ localDir, checkWorkingTreeClean }) where runLocalGit for `git reset --quiet HEAD -- .` throws. The catch block assembles a detail string from error.message, error.stderr, and error.stdout.","commonSituations":"The local git repo has no HEAD (empty repo with no commits); the index is corrupt (git reset cannot read it); a file in the working tree has a name that git cannot handle; disk I/O errors on the local filesystem; the repo was partially restored and is in an inconsistent state.","solutions":["Check the detail string for the specific git error (e.g. 'fatal: not a git repository', 'failed to read index').","Run `git fsck --full` in the localDir to check for repo corruption.","If the repo is empty (no HEAD), ensure the workspace clone completed before calling resetLocalGitIndexToHead.","Re-clone or re-restore the workspace if the git repo is corrupt beyond repair."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Verify the git repo is healthy before resetting\nasync function isGitRepoHealthy(localDir: string): Promise<boolean> {\n  try {\n    const result = await runLocalGit(localDir, [\"rev-parse\", \"--verify\", \"HEAD\"], { timeout: 5_000, maxBuffer: 1024 });\n    return (result.exitCode ?? 1) === 0;\n  } catch {\n    return false;\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await resetLocalGitIndexToHead({ localDir, checkWorkingTreeClean: true });\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"Failed to reset local git index to HEAD\")) {\n    // The detail string reveals the git-level failure\n    logger.error(`Git index reset failed: ${err.message}`);\n    // Consider re-cloning the workspace if the repo is corrupt\n  }\n  throw err;\n}","preventionTips":["Ensure the workspace clone completes before calling resetLocalGitIndexToHead.","Run `git fsck` periodically to detect repo corruption early.","Avoid concurrent git operations on the same localDir during workspace restore."],"tags":["git","workspace-sync","index","adapter-utils"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}