alibaba/open-code-review · critical

read rule file %q for pattern %q: %w

Error message

read rule file %q for pattern %q: %w

What it means

LoadDefault resolves each PathRules entry by reading rule_docs/<Rule> from the embedded FS. This error wraps that ReadFile failure and names both the missing rule file and the glob pattern that referenced it, so you know which map entry is broken.

Source

Thrown at internal/config/rules/system_rules.go:110

// LoadDefault parses the embedded system_rules.json and resolves rule file references.
func LoadDefault() (*SystemRule, error) {
	data, err := rulesFS.ReadFile("system_rules.json")
	if err != nil {
		return nil, fmt.Errorf("read embedded system_rules.json: %w", err)
	}
	var rule SystemRule
	if err := json.Unmarshal(data, &rule); err != nil {
		return nil, fmt.Errorf("unmarshal default system rules: %w", err)
	}
	content, err := rulesFS.ReadFile("rule_docs/" + rule.DefaultRule)
	if err != nil {
		return nil, fmt.Errorf("read default rule file %q: %w", rule.DefaultRule, err)
	}
	rule.DefaultRule = strings.TrimRight(string(content), "\n")
	for i := range rule.PathRules {
		content, err := rulesFS.ReadFile("rule_docs/" + rule.PathRules[i].Rule)
		if err != nil {
			return nil, fmt.Errorf("read rule file %q for pattern %q: %w", rule.PathRules[i].Rule, rule.PathRules[i].Pattern, err)
		}
		rule.PathRules[i].Rule = strings.TrimRight(string(content), "\n")
	}
	return &rule, nil
}

// loadObjCRule reads the embedded Objective-C rule doc used by the ".m"
// content sniff. It is not referenced from system_rules.json's path_rule_map,
// so it is loaded explicitly rather than through the PathRules loop.
func loadObjCRule() (string, error) {
	content, err := rulesFS.ReadFile("rule_docs/objc.md")
	if err != nil {
		return "", fmt.Errorf("read objc rule file: %w", err)
	}
	return strings.TrimRight(string(content), "\n"), nil
}

// RuleDetail contains the resolved rule along with metadata about its source.

View on GitHub (pinned to 5cf97d0d15)

Solutions

  1. Create the missing file at internal/config/rules/rule_docs/<name> or fix the path_rule_map value to reference an existing doc
  2. List rule_docs/ (ls internal/config/rules/rule_docs/) and correct the exact, case-sensitive filename
  3. If the rule text is obsolete, remove the pattern entry from path_rule_map instead

Example fix

// before
{"path_rule_map": {"**/*.py": "pyhton.md"}}
// after
{"path_rule_map": {"**/*.py": "python.md"}}  // rule_docs/python.md exists
Defensive patterns

Strategy: validation

Validate before calling

var probe struct {
	PathRuleMap map[string]string `json:"path_rule_map"`
}
if err := json.Unmarshal(systemRulesJSON, &probe); err != nil { return err }
for pattern, doc := range probe.PathRuleMap {
	if _, err := fs.Stat(docsFS, "rule_docs/"+doc); err != nil {
		return fmt.Errorf("pattern %q references missing doc %q", pattern, doc)
	}
}

Try / catch

rule, err := rules.LoadDefault()
if err != nil {
	if strings.Contains(err.Error(), "read rule file") {
		var missing string
		fmt.Sscanf(err.Error(), "read rule file %q", &missing)
		log.Fatalf("path_rule_map references missing doc %q — create it under rule_docs/ or fix the reference", missing)
	}
	return err
}

Prevention

When it happens

Trigger: A path_rule_map value in system_rules.json points to a rule doc that does not exist under rule_docs/ — filename typo, deleted file, case mismatch, or reference to a file living outside rule_docs/.

Common situations: Adding a pattern like "**/*.py": "python.md" without creating rule_docs/python.md; renaming docs during cleanup; case-sensitive FS mismatch (Go.md vs go.md).

Related errors


AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02). Data as JSON: /api/errors/56c059afa2ff7e00. Report an issue: GitHub.