alibaba/open-code-review · error

read path_rule_map value for

Error message

read path_rule_map value for %q: %w

What it means

SystemRule.UnmarshalJSON streams path_rule_map with a json.Decoder and decodes each value into a plain string. This error wraps the json.Decoder.Decode failure, meaning the value for the given key is not a JSON string (e.g. an object, array, number, bool, or malformed JSON). It exists so the offending pattern name is preserved in the message.

Solutions

  1. Open the rule JSON (embedded system_rules.json or the project/global rule file being parsed) and make every path_rule_map value a plain JSON string naming a rule doc file
  2. Validate the JSON with a linter (jq) before shipping: jq '.path_rule_map' rule.json — every value must be a string
  3. If a value needs structured data, change the schema and UnmarshalJSON, do not nest it under path_rule_map

Example fix

// before
{"path_rule_map": {"**/*.go": {"rule": "golang.md"}}}
// after
{"path_rule_map": {"**/*.go": "golang.md"}}
Defensive patterns

Strategy: validation

Validate before calling

raw, err := os.ReadFile(cfgPath)
if err != nil { return err }
var probe struct {
	PathRuleMap map[string]json.RawMessage `json:"path_rule_map"`
}
if err := json.Unmarshal(raw, &probe); err != nil { return err }
for k, v := range probe.PathRuleMap {
	var s string
	if err := json.Unmarshal(v, &s); err != nil {
		return fmt.Errorf("path_rule_map[%q] must be a string, got: %s", k, v)
	}
}

Type guard

func isStringJSON(b json.RawMessage) bool {
	var s string
	return json.Unmarshal(b, &s) == nil
}

Try / catch

var rule rules.SystemRule
if err := json.Unmarshal(data, &rule); err != nil {
	var sint *json.SyntaxError
	var ute *json.UnmarshalTypeError
	switch {
	case errors.As(err, &sint): log.Fatalf("invalid JSON at offset %d: %v", sint.Offset, err)
	case errors.As(err, &ute): log.Fatalf("wrong type at %s: %v", ute.Field, err)
	default: log.Fatalf("path_rule_map value error: %v", err)
	}
}

Prevention

When it happens

Trigger: json.Unmarshal into SystemRule where any value inside path_rule_map is not a JSON string, or the map is truncated/malformed after a key. Example: {"path_rule_map":{"**/*.go":{}}} or {"path_rule_map":{"**/*.go":}}.

Common situations: Hand-edited or generated rule config where someone put an object/array as the rule value instead of a rule file reference string; a template expansion that left an empty or nested value; encoding corruption after a key.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

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

		return fmt.Errorf("expected '{' in path_rule_map: %w", err)
	}
	if t != json.Delim('{') {
		return fmt.Errorf("expected '{' in path_rule_map, got %v", t)
	}
	for dec.More() {
		// Read key
		keyTok, err := dec.Token()
		if err != nil {
			return fmt.Errorf("read path_rule_map key: %w", err)
		}
		key, ok := keyTok.(string)
		if !ok {
			return fmt.Errorf("expected string key in path_rule_map, got %T", keyTok)
		}
		// Read value
		var value string
		if err := dec.Decode(&value); err != nil {
			return fmt.Errorf("read path_rule_map value for %q: %w", key, err)
		}
		r.PathRules = append(r.PathRules, PathRule{Pattern: key, Rule: value})
	}
	return nil
}

//go:embed system_rules.json rule_docs/*
var rulesFS embed.FS

// 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)

View on GitHub (pinned to 5cf97d0d15)