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

  1. Validate the JSON syntax of scan_template.json (jq . scan_template.json) and fix the error at the reported position
  2. Cross-check keys against ScanTemplate's json tags and correct names/types
  3. Make sure the file is plain UTF-8 without BOM
  4. 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

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


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