alibaba/open-code-review · error

read objc rule file: %w

Error message

read objc rule file: %w

What it means

loadObjCRule reads the embedded rule_docs/objc.md used by the '.m' content sniffer. It is loaded outside the path_rule_map loop, so a missing objc.md fails independently of system_rules.json. This error wraps that ReadFile failure.

Source

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

	}
	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.
type RuleDetail struct {
	Rule    string // rule text
	Source  string // "custom" | "project" | "global" | "system"
	Pattern string // glob pattern that matched, or "default" for fallback — always a plain glob, never annotated
	// SniffedAs is "" for a plain path match, or the sniffed language (e.g.
	// "objc") when content sniffing overrode the path-based rule. Internal
	// only: callers that serialize RuleDetail (e.g. delegateRuleGroupJSON)
	// must not surface this, since Pattern is a versioned "the glob that
	// matched" contract that a sniff annotation would silently break.
	SniffedAs string `json:"-"`
}

// DetailResolver extends Resolver with source metadata.

View on GitHub (pinned to 5cf97d0d15)

Solutions

  1. Restore or recreate internal/config/rules/rule_docs/objc.md, or update loadObjCRule to the new filename
  2. Confirm the //go:embed pattern still covers rule_docs/*
  3. Run go build and the rules package tests to confirm the embed succeeded

Example fix

// before
content, err := rulesFS.ReadFile("rule_docs/objc.md")
// after (renamed doc)
content, err := rulesFS.ReadFile("rule_docs/objective-c.md")
Defensive patterns

Strategy: fallback

Validate before calling

if _, err := fs.Stat(docsFS, "rule_docs/objc.md"); err != nil {
	// objc sniff will be unavailable; warn at startup
}

Try / catch

if _, err := rules.LoadDefault(); err != nil {
	if strings.Contains(err.Error(), "read objc rule file") {
		log.Printf("warning: Objective-C sniff rule unavailable (%v); .m files fall back to path rules", err)
		return err // or degrade gracefully depending on caller
	}
	return err
}

Prevention

When it happens

Trigger: rulesFS.ReadFile("rule_docs/objc.md") fails because the file was deleted, renamed, or excluded from the //go:embed rule_docs/* pattern at build time.

Common situations: Cleanup removing a 'single-purpose' doc; renaming objc.md to objective-c.md while the sniffer still requests 'objc.md'; embed pattern narrowed to an explicit list that omitted objc.md.

Related errors


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