alibaba/open-code-review · error
parse grouping JSON: %w
Error message
parse grouping JSON: %w
What it means
parseGroupingResponse wraps json.Unmarshal failures when converting the LLM's response content into []groupingResponse. Before unmarshalling it trims whitespace and strips a single markdown code fence, but any remaining non-JSON or malformed JSON causes this error. It is the underlying cause of the 'grouping response parse failed' recorded message in callGroupingLLM.
Source
Thrown at internal/agent/grouping.go:269
}
func parseGroupingResponse(content string, diffs []model.Diff) ([]FileGroup, error) {
content = strings.TrimSpace(content)
// Strip markdown code fences if present
if strings.HasPrefix(content, "```") {
lines := strings.Split(content, "\n")
if len(lines) >= 2 {
lines = lines[1:]
}
if len(lines) > 0 && strings.HasPrefix(strings.TrimSpace(lines[len(lines)-1]), "```") {
lines = lines[:len(lines)-1]
}
content = strings.Join(lines, "\n")
}
var resp []groupingResponse
if err := json.Unmarshal([]byte(content), &resp); err != nil {
return nil, fmt.Errorf("parse grouping JSON: %w", err)
}
diffByPath := make(map[string]model.Diff, len(diffs))
for _, d := range diffs {
diffByPath[d.NewPath] = d
}
seen := make(map[string]bool, len(diffs))
var groups []FileGroup
for _, g := range resp {
var gDiffs []model.Diff
for _, f := range g.Files {
if seen[f] {
// Skip duplicate — file already assigned to an earlier group
continue
}
d, ok := diffByPath[f]View on GitHub (pinned to 5cf97d0d15)
Solutions
- Read the wrapped %w error to see the exact json.Unmarshal syntax failure and byte offset
- Raise maxTokens (default 4096) for large diffs so output is not truncated
- Tighten the prompt to forbid any text outside a bare JSON array
- Pre-process content to extract the outermost [...] span before unmarshalling
- Retry the LLM call — non-deterministic output often parses on a second attempt
Example fix
// before
if err := json.Unmarshal([]byte(content), &resp); err != nil {
return nil, fmt.Errorf("parse grouping JSON: %w", err)
}
// after: salvage a JSON array embedded in prose
start := strings.Index(content, "["); end := strings.LastIndex(content, "]")
if start >= 0 && end > start { content = content[start : end+1] }
if err := json.Unmarshal([]byte(content), &resp); err != nil {
return nil, fmt.Errorf("parse grouping JSON: %w", err)
} Defensive patterns
Strategy: validation
Validate before calling
func parseableGrouping(content string) error {
c := strings.TrimSpace(content)
if i := strings.Index(c, "["); i >= 0 {
if j := strings.LastIndex(c, "]"); j > i { c = c[i : j+1] }
}
var probe []map[string]any
return json.Unmarshal([]byte(c), &probe)
} Type guard
func isGroupingShape(v any) bool {
arr, ok := v.([]any)
if !ok { return false }
for _, e := range arr {
m, ok := e.(map[string]any)
if !ok { return false }
if _, ok := m["files"]; !ok { return false }
}
return len(arr) > 0
} Try / catch
groups, err := parseGroupingResponse(content, diffs)
if err != nil {
var syntaxErr *json.SyntaxError
if errors.As(err, &syntaxErr) {
log.Errorf("bad JSON at offset %d: %v", syntaxErr.Offset, syntaxErr)
}
return retryOrFallback(diffs)
} Prevention
- Increase maxTokens for large diffs (default 4096 truncates long file lists)
- Demand bare JSON in the prompt and strip markdown fences defensively
- Salvage the outermost [...] before unmarshalling
- Log the raw content on failure so the offending text is visible
When it happens
Trigger: The LLM content is not a syntactically valid JSON array — truncated output, prose around the JSON, single quotes instead of double, trailing commas, or a JSON object where an array is expected.
Common situations: max_tokens too low so the array is cut off mid-file; model adds commentary like 'Here is the grouping:'; provider returns the JSON inside nested code fences; locale/format drift in a model upgrade.
Related errors
- grouping response parse failed: %w
- grouping LLM panicked: %v
- grouping LLM call: %w
- grouping LLM returned empty response
- resolve LLM endpoint: %w
AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02).
Data as JSON: /api/errors/008df8c932878462.
Report an issue: GitHub.