alibaba/open-code-review · error
unmarshal default scan template: %w
Error message
unmarshal default scan template: %w
What it means
LoadScanDefault unmarshals the embedded scan_template.json bytes (defaultScanTemplate) into ScanTemplate. If that JSON is invalid or incompatible with ScanTemplate's fields, the error is wrapped as 'unmarshal default scan template'. Like the other template errors, the data is compiled in, so this signals a broken source tree rather than a user-fixable runtime config.
Source
Thrown at internal/config/template/template.go:261
return nil, fmt.Errorf("MEMORY_COMPRESSION_TASK: %w", err)
}
if tpl.ReLocationTask, err = resolveOptionalConversation(m.ReLocationTask, "RE_LOCATION_TASK"); err != nil {
return nil, err
}
if tpl.ReviewFilterTask, err = resolveOptionalConversation(m.ReviewFilterTask, "REVIEW_FILTER_TASK"); err != nil {
return nil, err
}
if tpl.GroupingTask, err = resolveOptionalConversation(m.GroupingTask, "GROUPING_TASK"); err != nil {
return nil, err
}
return &tpl, nil
}
// LoadScanDefault parses the embedded scan_template.json.
func LoadScanDefault() (*ScanTemplate, error) {
var tpl ScanTemplate
if err := json.Unmarshal(defaultScanTemplate, &tpl); err != nil {
return nil, fmt.Errorf("unmarshal default scan template: %w", err)
}
return &tpl, nil
}
// applyLanguage appends instruction to all system-role messages in conv.
func applyLanguage(conv *LlmConversation, instruction string) {
for i := range conv.Messages {
if conv.Messages[i].Role == "system" {
conv.Messages[i].Content += instruction
}
}
}
// resolveLang returns the resolved language name for the instruction.
func resolveLang(lang string) string {
if lang == "" {
return "English"
}View on GitHub (pinned to 5cf97d0d15)
Solutions
- Validate the JSON syntax of scan_template.json (jq . scan_template.json) and fix the error at the reported position
- Cross-check keys against ScanTemplate's json tags and correct names/types
- Make sure the file is plain UTF-8 without BOM
- Rebuild so the corrected file is re-embedded into the binary
Example fix
// before (scan_template.json)
{"MAX_TOKENS": "4096", "MAIN_TASK": {"messages": []}}
// after
{"MAX_TOKENS": 4096, "MAIN_TASK": {"messages": []}} Defensive patterns
Strategy: validation
Validate before calling
var probe map[string]any
if err := json.Unmarshal(scanTemplateBytes, &probe); err != nil {
log.Fatalf("scan_template.json invalid: %v", err)
}
if _, ok := probe["MAX_TOKENS"].(float64); !ok { log.Fatal("scan_template.json MAX_TOKENS must be a number") } Try / catch
stpl, err := template.LoadScanDefault()
if err != nil {
var typeErr *json.UnmarshalTypeError
if errors.As(err, &typeErr) {
return fmt.Errorf("scan_template.json field %s has incompatible type: %w", typeErr.Field, err)
}
return fmt.Errorf("scan template invalid: %w", err)
} Prevention
- Validate scan_template.json with a linter in CI before go build
- Keep ScanTemplate json tags and the JSON keys in sync via a round-trip test
- Avoid scripts that regenerate the JSON without validating output
When it happens
Trigger: Calling LoadScanDefault() when defaultScanTemplate (from //go:embed scan_template.json) is not valid JSON or has fields whose types don't match ScanTemplate (e.g. MAX_TOKENS as a string, messages not an array).
Common situations: A bad merge left conflict markers in scan_template.json; a field was renamed in ScanTemplate but not in the JSON; hand-editing introduced a syntax error; the file was regenerated by a script with wrong types.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- unmarshal task_template manifest: %w
- parse config: %w
- parse app config: %w
- load app config: %w
- read path_rule_map value for %q: %w
AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02).
Data as JSON: /api/errors/ca6c792bff9569c8.
Report an issue: GitHub.