alibaba/open-code-review · error

read path_rule_map value for %q: %w

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.

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)

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.