alibaba/open-code-review · error
resolve repo dir %s: %w
Error message
resolve repo dir %s: %w
What it means
loadProjectRule first canonicalizes the repository directory via pathutil.CanonicalPath before locating .opencodereview/rule.json. If that canonicalization fails (e.g. the path cannot be made absolute/clean because the directory is missing or the path is malformed), the error is wrapped with the repo dir for context. It is thrown by NewResolver during resolver construction, so review runs abort early.
Source
Thrown at internal/config/rules/system_rules.go:414
return nil, fmt.Errorf("read rule file %s: %w", path, err)
}
var pr ProjectRule
if err := json.Unmarshal(data, &pr); err != nil {
return nil, fmt.Errorf("unmarshal rule file %s: %w", path, err)
}
resolveRuleEntries(pr.Rules, filepath.Dir(path), "")
return &pr, nil
}
// loadProjectRule reads <repoDir>/.opencodereview/rule.json. Since #287 anchored
// RepoDir at the git top-level, `ocr review` from a monorepo subdirectory loads
// the repo-root rule file — which is consistent, since rule entries match against
// root-relative diff paths. A subproject-local rule.json under the subdirectory is
// intentionally not consulted; put shared rules at the repo root, or pass --rule.
func loadProjectRule(repoDir string) (*ProjectRule, error) {
confineRoot, err := pathutil.CanonicalPath(repoDir)
if err != nil {
return nil, fmt.Errorf("resolve repo dir %s: %w", repoDir, err)
}
path := filepath.Join(repoDir, ".opencodereview", "rule.json")
resolved, err := filepath.EvalSymlinks(path)
if err != nil {
if os.IsNotExist(err) {
return nil, nil
}
return nil, fmt.Errorf("resolve project rule %s: %w", path, err)
}
if !pathutil.WithinBase(confineRoot, resolved) {
fmt.Fprintf(os.Stderr, "[ocr] WARNING: project rule file escapes repo dir: %s\n", path)
return nil, nil
}
data, err := os.ReadFile(resolved)
if err != nil {
if os.IsNotExist(err) {View on GitHub (pinned to 5cf97d0d15)
Solutions
- Run the tool from inside an existing git repository or pass --repo with a valid absolute directory
- Check that the repo dir actually exists before invoking ocr (e.g. `ls <repoDir>`)
- Inspect the wrapped inner error (%w) from pathutil.CanonicalPath to see the root cause
Example fix
// before ocr review --repo ./rpovider-service // after ocr review --repo ./provider-service
Defensive patterns
Strategy: validation
Validate before calling
import "path/filepath"
func ensureRepoDir(dir string) error {
if dir == "" { return fmt.Errorf("repo dir is empty") }
abs, err := filepath.Abs(dir)
if err != nil { return err }
info, err := os.Stat(abs)
if err != nil { return fmt.Errorf("repo dir %s: %w", abs, err) }
if !info.IsDir() { return fmt.Errorf("%s is not a directory", abs) }
return nil
} Try / catch
rule, err := rules.NewResolver(repoDir)
if err != nil {
var pathErr *os.PathError
if errors.As(err, &pathErr) {
fmt.Fprintf(os.Stderr, "bad repo dir %s: %v\n", pathErr.Path, pathErr.Err)
os.Exit(2)
}
return err
} Prevention
- Always run ocr from inside a checked-out git repository
- Validate the --repo path exists and is a directory before invoking
- Prefer absolute paths in scripts/CI to avoid cwd confusion
When it happens
Trigger: NewResolver is invoked with a --repo or repoDir value that CanonicalPath cannot resolve: an empty path, a nonexistent directory, or a path that fails the underlying transformation.
Common situations: Running `ocr review` outside a git repo so the detected repo dir is empty; passing a typo'd --repo flag; a CI checkout that has not happened yet so the target dir does not exist.
Related errors
- read project rule %s: %w
- resolve file %q: %w
- read background file %q: %w
- background file %q is a directory, not a file
- MCP server %q not found
AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02).
Data as JSON: /api/errors/03e5d465d9615b7a.
Report an issue: GitHub.