{"record":{"id":"caac53be20f49107","repo":"alibaba/open-code-review","slug":"read-objc-rule-file-w","errorCode":null,"errorMessage":"read objc rule file: %w","messagePattern":"read objc rule file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/config/rules/system_rules.go","lineNumber":123,"sourceCode":"\t}\n\trule.DefaultRule = strings.TrimRight(string(content), \"\\n\")\n\tfor i := range rule.PathRules {\n\t\tcontent, err := rulesFS.ReadFile(\"rule_docs/\" + rule.PathRules[i].Rule)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"read rule file %q for pattern %q: %w\", rule.PathRules[i].Rule, rule.PathRules[i].Pattern, err)\n\t\t}\n\t\trule.PathRules[i].Rule = strings.TrimRight(string(content), \"\\n\")\n\t}\n\treturn &rule, nil\n}\n\n// loadObjCRule reads the embedded Objective-C rule doc used by the \".m\"\n// content sniff. It is not referenced from system_rules.json's path_rule_map,\n// so it is loaded explicitly rather than through the PathRules loop.\nfunc loadObjCRule() (string, error) {\n\tcontent, err := rulesFS.ReadFile(\"rule_docs/objc.md\")\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"read objc rule file: %w\", err)\n\t}\n\treturn strings.TrimRight(string(content), \"\\n\"), nil\n}\n\n// RuleDetail contains the resolved rule along with metadata about its source.\ntype RuleDetail struct {\n\tRule    string // rule text\n\tSource  string // \"custom\" | \"project\" | \"global\" | \"system\"\n\tPattern string // glob pattern that matched, or \"default\" for fallback — always a plain glob, never annotated\n\t// SniffedAs is \"\" for a plain path match, or the sniffed language (e.g.\n\t// \"objc\") when content sniffing overrode the path-based rule. Internal\n\t// only: callers that serialize RuleDetail (e.g. delegateRuleGroupJSON)\n\t// must not surface this, since Pattern is a versioned \"the glob that\n\t// matched\" contract that a sniff annotation would silently break.\n\tSniffedAs string `json:\"-\"`\n}\n\n// DetailResolver extends Resolver with source metadata.","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/alibaba/open-code-review/blob/5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f/internal/config/rules/system_rules.go#L105-L141","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Restore or recreate internal/config/rules/rule_docs/objc.md, or update loadObjCRule to the new filename","Confirm the //go:embed pattern still covers rule_docs/*","Run go build and the rules package tests to confirm the embed succeeded"],"exampleFix":"// before\ncontent, err := rulesFS.ReadFile(\"rule_docs/objc.md\")\n// after (renamed doc)\ncontent, err := rulesFS.ReadFile(\"rule_docs/objective-c.md\")","handlingStrategy":"fallback","validationCode":"if _, err := fs.Stat(docsFS, \"rule_docs/objc.md\"); err != nil {\n\t// objc sniff will be unavailable; warn at startup\n}","typeGuard":null,"tryCatchPattern":"if _, err := rules.LoadDefault(); err != nil {\n\tif strings.Contains(err.Error(), \"read objc rule file\") {\n\t\tlog.Printf(\"warning: Objective-C sniff rule unavailable (%v); .m files fall back to path rules\", err)\n\t\treturn err // or degrade gracefully depending on caller\n\t}\n\treturn err\n}","preventionTips":["Treat rule_docs/objc.md as load-bearing for the .m content sniffer — do not delete it in cleanups","Keep the //go:embed rule_docs/* wildcard so new docs are picked up automatically","Add a test asserting the sniffer's rule text is non-empty"],"tags":["embed","missing-file","go"],"backgroundTag":"embedded-asset-missing","analyzedSha":"5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f","analyzedAt":"2026-09-02T02:08:09.116Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}