{"record":{"id":"75db406ef11f3930","repo":"alibaba/open-code-review","slug":"resolve-repository-path-q-w","errorCode":null,"errorMessage":"resolve repository path %q: %w","messagePattern":"resolve repository path %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/diff/workspace_file.go","lineNumber":17,"sourceCode":"// SPDX-License-Identifier: Apache-2.0\n// Copyright 2026 alibaba/open-code-review Contributors\n\npackage diff\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/alibaba/open-code-review/internal/pathutil\"\n)\n\nfunc readWorkspaceFileForDiff(repoDir, relPath string) ([]byte, error) {\n\trepoRoot, err := pathutil.CanonicalPath(repoDir)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"resolve repository path %q: %w\", repoDir, err)\n\t}\n\tif filepath.IsAbs(relPath) {\n\t\treturn nil, fmt.Errorf(\"file path %q must be relative, not absolute\", relPath)\n\t}\n\n\tfullPath := filepath.Join(repoRoot, relPath)\n\tif !pathutil.WithinBase(repoRoot, fullPath) {\n\t\treturn nil, fmt.Errorf(\"file path %q is outside repository\", relPath)\n\t}\n\n\tparent, err := filepath.EvalSymlinks(filepath.Dir(fullPath))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"resolve parent path for %q: %w\", relPath, err)\n\t}\n\tif !pathutil.WithinBase(repoRoot, parent) {\n\t\treturn nil, fmt.Errorf(\"file path %q is outside repository\", relPath)\n\t}\n","sourceCodeStart":1,"sourceCodeEnd":35,"githubUrl":"https://github.com/alibaba/open-code-review/blob/5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f/internal/diff/workspace_file.go#L1-L35","documentation":"readWorkspaceFileForDiff first canonicalizes the repository directory via pathutil.CanonicalPath; failure is wrapped as 'resolve repository path %q'. This usually means the repo directory does not exist, is inaccessible, or cannot be resolved to an absolute canonical path, so no workspace file diffing can proceed.","triggerScenarios":"Calling readWorkspaceFileForDiff (via untrackedFileDiffs/finalizeDiff during workspace diffing) with a repoDir that fails pathutil.CanonicalPath — nonexistent directory, permission issues on ancestors, or symlink/eval resolution errors.","commonSituations":"Running the diff against a stale/deleted checkout path; passing a relative repo dir from a different working directory; symlinked repo roots that no longer resolve; permission restrictions in containers/CI workspaces.","solutions":["Verify the repo directory exists and pass an absolute path (filepath.Abs or os.Getwd-based)","Check read/execute permissions on the directory and its ancestors","Remove or fix broken symlinks in the repo path","Inspect the wrapped inner error (%w) for the exact filesystem failure"],"exampleFix":"// before\ndiffs, err := diff.GetDiff(ctx, params{dir: \"../maybe-moved-repo\"})\n// after\nabs, err := filepath.Abs(\"../repo\")\nif err != nil { return err }\nif _, err := os.Stat(abs); err != nil { return err }\ndiffs, err := diff.GetDiff(ctx, params{dir: abs})","handlingStrategy":"validation","validationCode":"abs, err := filepath.Abs(repoDir)\nif err != nil { return err }\ninfo, err := os.Stat(abs)\nif err != nil || !info.IsDir() { return fmt.Errorf(\"repo dir %s unusable: %w\", abs, err) }","typeGuard":null,"tryCatchPattern":"d, err := differ.GetDiff(ctx, p)\nif err != nil && strings.HasPrefix(err.Error(), \"resolve repository path\") {\n    var pathErr *os.PathError\n    if errors.As(err, &pathErr) { return fmt.Errorf(\"repo path bad: %w\", pathErr) }\n    return err\n}","preventionTips":["Pass absolute, existing repo directories into the diff API","Re-resolve repo paths after checkouts/moves instead of caching them","Check symlink targets still exist in containerized/CI workspaces"],"tags":["filesystem","path-resolution","workspace","diff"],"backgroundTag":"path-resolution-failed","analyzedSha":"5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f","analyzedAt":"2026-09-02T02:08:09.116Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}