alibaba/open-code-review · error
expected '{' in path_rule_map: %w
Error message
expected '{' in path_rule_map: %w What it means
SystemRule.UnmarshalJSON's ordered-key parser failed at its first json.Decoder.Token() call while reading the opening brace of the path_rule_map value. The %w wraps the decoder's error (unexpected EOF, invalid character), meaning path_rule_map is present in the JSON but its value is not a well-formed JSON object. Order preservation for PathRules requires a streaming decode, so a broken value aborts unmarshalling entirely.
Source
Thrown at internal/config/rules/system_rules.go:64
}
r.DefaultRule = wrapper.DefaultRule
// Use json.Decoder with UseNumber to preserve order of path_rule_map keys.
var raw map[string]json.RawMessage
if err := json.Unmarshal(data, &raw); err != nil {
return err
}
mapData, ok := raw["path_rule_map"]
if !ok || len(mapData) == 0 || string(mapData) == "null" {
return nil
}
// Parse ordered keys using a streaming decoder.
dec := json.NewDecoder(strings.NewReader(string(mapData)))
// Read opening '{'
t, err := dec.Token()
if err != nil {
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)View on GitHub (pinned to 5cf97d0d15)
Solutions
- Validate the whole rules file with a JSON linter / 'jq .' before loading
- Check the path_rule_map value specifically — it must be a complete {"pattern":"rule"} object
- Fix truncation or stray characters around the path_rule_map block
- If path_rule_map is optional, either omit the key or set it to null (both are handled) rather than an empty/broken value
Example fix
// before (truncated)
"path_rule_map": {"*.go": "golang"
// after
"path_rule_map": {"*.go": "golang.md"} Defensive patterns
Strategy: validation
Validate before calling
func validRulesConfig(data []byte) error {
var probe map[string]json.RawMessage
if err := json.Unmarshal(data, &probe); err != nil { return err }
m, ok := probe["path_rule_map"]
if !ok || string(m) == "null" { return nil }
var obj map[string]string
return json.Unmarshal(m, &obj) // catches truncated/broken objects early
} Type guard
func isPathRuleMap(v json.RawMessage) bool {
var obj map[string]string
return len(v) > 0 && string(v) != "null" && json.Unmarshal(v, &obj) == nil
} Try / catch
rule, err := rules.LoadDefault()
if err != nil {
var dec *json.SyntaxError
if errors.As(err, &dec) {
return fmt.Errorf("malformed rules config at offset %d: %w", dec.Offset, err)
}
return err
} Prevention
- Run 'jq .' on custom rules files before shipping them
- Never commit partially edited config; validate in CI
- Keep path_rule_map as a complete JSON object or omit/null it
- Lint configs after any generation step that writes them
When it happens
Trigger: Custom rules JSON where "path_rule_map" is present but its value is syntactically invalid JSON (truncated file, missing closing brace, stray characters), so dec.Token() errors instead of returning a Delim.
Common situations: Hand-edited rules files saved mid-edit; config generated by a script that emitted invalid JSON; copy-paste that dropped the closing '}' or merged two objects.
Related errors
- expected '{' in path_rule_map, got %v
- read path_rule_map key: %w
- expected string key in path_rule_map, got %T
- load rules: %w
- load config: %w
AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02).
Data as JSON: /api/errors/7e514d08109d5883.
Report an issue: GitHub.