alibaba/open-code-review · error
read global rule %s: %w
Error message
read global rule %s: %w
What it means
loadGlobalRule reads ~/.opencodereview/rule.json; a missing file is tolerated (returns nil, nil), but any other read failure (permissions, is-a-directory, I/O error) is wrapped in this error with the full path. Unlike missing, these indicate a real environment problem.
Source
Thrown at internal/config/rules/system_rules.go:383
f.Exclude = append(f.Exclude, strings.ToLower(p))
}
return f
}
return nil
}
func loadGlobalRule() (*ProjectRule, error) {
home, err := os.UserHomeDir()
if err != nil {
return nil, nil
}
path := filepath.Join(home, ".opencodereview", "rule.json")
data, err := os.ReadFile(path)
if err != nil {
if os.IsNotExist(err) {
return nil, nil
}
return nil, fmt.Errorf("read global rule %s: %w", path, err)
}
var pr ProjectRule
if err := json.Unmarshal(data, &pr); err != nil {
return nil, fmt.Errorf("unmarshal global rule: %w", err)
}
resolveRuleEntries(pr.Rules, filepath.Dir(path), "")
return &pr, nil
}
func loadRuleFile(path string) (*ProjectRule, error) {
data, err := os.ReadFile(path)
if err != nil {
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)
}View on GitHub (pinned to 5cf97d0d15)
Solutions
- Check the file: ls -la ~/.opencodereview/rule.json — if it's a directory, remove it and create a regular JSON file
- Fix permissions so the running user can read it (chmod u+r)
- Verify $HOME points to the intended directory; the path in the error message shows exactly what was opened
Example fix
// before: rule.json is a directory or unreadable
$ ls -la ~/.opencodereview/rule.json # drwxr-xr-x
// after
$ rm -rf ~/.opencodereview/rule.json
$ echo '{"rules": []}' > ~/.opencodereview/rule.json Defensive patterns
Strategy: try-catch
Validate before calling
p := filepath.Join(os.Getenv("HOME"), ".opencodereview", "rule.json")
if fi, err := os.Stat(p); err == nil && fi.IsDir() {
return fmt.Errorf("%s is a directory; expected a JSON file", p)
}
if fi, err := os.Stat(p); err == nil && fi.Mode().Perm()&0o400 == 0 {
return fmt.Errorf("%s is not readable by the current user", p)
} Try / catch
// loadGlobalRule treats ErrNotExist as 'no config'; wrap the call site:
pr, err := loadGlobalRule()
if err != nil {
if errors.Is(err, os.ErrPermission) {
log.Printf("warning: cannot read global rule (permissions): %v — continuing without it", err)
} else {
return err
}
} Prevention
- Check ls -la ~/.opencodereview/rule.json after restoring backups or changing $HOME
- Never create rule.json as a directory; create it with a text editor or printf
- In containers/CI, ensure $HOME points to a writable, readable location
When it happens
Trigger: os.ReadFile on $HOME/.opencodereview/rule.json fails with an error other than fs.ErrNotExist — e.g. EACCES on a unreadable file, EISDIR because rule.json is a directory, or a symlink loop.
Common situations: rule.json created as a directory by mistake; file owned by root or with 000 permissions after restoring from backup; $HOME pointing at an unwritable/odd location (containers, CI).
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02).
Data as JSON: /api/errors/c81cd7cbd692a406.
Report an issue: GitHub.