{"record":{"id":"3a66948bc04184e2","repo":"GoogleContainerTools/skaffold","slug":"failed-to-remove-repo-cache-dir-w","errorCode":null,"errorMessage":"failed to remove repo cache dir: %w","messagePattern":"failed to remove repo cache dir: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/skaffold/git/gitutil.go","lineNumber":136,"sourceCode":"\thash, err := getRepoDir(g)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to clone git repo: unable to create directory name: %w\", err)\n\t}\n\trepoCacheDir := filepath.Join(skaffoldCacheDir, hash)\n\tif _, err := os.Stat(repoCacheDir); os.IsNotExist(err) {\n\t\tif opts.SyncRemoteCache.CloneDisabled() {\n\t\t\treturn \"\", SyncDisabledErr(g, repoCacheDir)\n\t\t}\n\t\tif _, err := r.Run(ctx, \"clone\", g.RepoCloneURI, fmt.Sprintf(\"./%s\", hash), \"--branch\", ref, \"--depth\", \"1\"); err != nil {\n\t\t\tif strings.Contains(err.Error(), \"Could not find remote branch\") {\n\t\t\t\tif _, err := r.Run(ctx, \"clone\", g.RepoCloneURI, fmt.Sprintf(\"./%s\", hash), \"--depth\", \"1\"); err != nil {\n\t\t\t\t\treturn \"\", fmt.Errorf(\"failed to clone repo: %w\", err)\n\t\t\t\t}\n\n\t\t\t\tr.Dir = repoCacheDir\n\t\t\t\tif _, err := r.Run(ctx, \"checkout\", ref); err != nil {\n\t\t\t\t\tif rmErr := os.RemoveAll(repoCacheDir); rmErr != nil {\n\t\t\t\t\t\terr = fmt.Errorf(\"failed to remove repo cache dir: %w\", rmErr)\n\t\t\t\t\t}\n\n\t\t\t\t\treturn \"\", fmt.Errorf(\"failed to checkout commit: %w\", err)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn \"\", fmt.Errorf(\"failed to clone repo: %w\", err)\n\t\t\t}\n\t\t}\n\t} else {\n\t\tr.Dir = repoCacheDir\n\t\t// check remote is defined\n\t\tif remotes, err := r.Run(ctx, \"remote\", \"-v\"); err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"failed to clone repo %s: trouble checking repository remote; run 'git clone <REPO>; stat <DIR/SUBDIR>' to verify credentials: %w\", g.Repo, err)\n\t\t} else if len(remotes) == 0 {\n\t\t\treturn \"\", fmt.Errorf(\"failed to clone repo %s: remote not set for existing clone\", g.Repo)\n\t\t}\n\n\t\t// if sync property is false, then skip fetching latest from remote and resetting the branch.","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/git/gitutil.go#L118-L154","documentation":"Thrown by syncRepo when, after a branch-less fallback clone succeeded, `git checkout <ref>` inside the fresh clone fails AND the cleanup os.RemoveAll(repoCacheDir) also fails. The RemoveAll error is wrapped into this message and stuffed into err, so the developer sees why cleanup failed. The user still gets the checkout failure wrapped in 'failed to checkout commit'.","triggerScenarios":"Ref not found in the cloned default branch after the fallback clone, plus os.RemoveAll(repoCacheDir) failing to delete the half-cloned cache dir (files held open, permission loss, NFS stale handles).","commonSituations":"Typo'd ref (e.g. 'Main' vs 'main'); ref exists on another remote but not origin; cache dir on a network filesystem where RemoveAll fails mid-way; permissions changed by a concurrent process.","solutions":["Delete the stale/partial cache dir manually: rm -rf <cache-dir>/<hash>, then retry.","Verify the ref exists: git ls-remote <URI> <ref> — correct typos or use the full ref name (refs/heads/<ref>).","If RemoveAll keeps failing, check mounts/permissions on the cache directory and ensure no process locks files there.","Set ref explicitly in config so the branch-less fallback + checkout path is avoided."],"exampleFix":"// before\nrepo: https://github.com/org/repo#Mian    # typo, checkout fails\n// after\nrepo: https://github.com/org/repo#main","handlingStrategy":"try-catch","validationCode":"const { execSync } = require('child_process');\nfunction refExists(uri, ref) {\n  try { execSync(`git ls-remote --exit-code ${uri} ${ref}`, { stdio: 'pipe' }); return true; }\n  catch { return false; }\n}","typeGuard":"null","tryCatchPattern":"try {\n  await syncRepo(g, ctx, opts);\n} catch (err) {\n  if (/failed to checkout commit|failed to remove repo cache dir/.test(err.message)) {\n    // cleanup the poisoned cache dir ourselves, then retry once\n    fs.rmSync(path.join(cacheDir, hashFor(g)), { recursive: true, force: true });\n    return syncRepo(g, ctx, opts);\n  }\n  throw err;\n}","preventionTips":["Validate the ref with git ls-remote --exit-code before configuring it.","Use exact branch/tag names (case-sensitive) in config.","Keep the cache dir on a local, non-NFS filesystem so RemoveAll works.","Prefer pinned branches over raw SHAs with shallow clones."],"tags":["git","filesystem","cleanup"],"backgroundTag":"checkout-ref-not-found","analyzedSha":"a1189de023efc32d4b8e11f395acc678aa555011","analyzedAt":"2026-09-05T12:09:27.064Z","contentChangedAt":"2026-09-05T12:09:27.064Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}