alibaba/open-code-review · error

MAIN_TASK: %w

Error message

MAIN_TASK: %w

What it means

LoadDefault resolves the MAIN_TASK conversation by reading each message's prompt file from the embedded FS via resolveConversation. If a referenced prompt file (m.MainTask.Messages[i].PromptFile) cannot be read, the error is wrapped as 'MAIN_TASK: ...'. This means the manifest's main task references a prompt file that is missing from the embedded assets.

Source

Thrown at internal/config/template/template.go:237

		return nil, fmt.Errorf("read embedded task_template.json: %w", err)
	}
	var m templateManifest
	if err := json.Unmarshal(data, &m); err != nil {
		return nil, fmt.Errorf("unmarshal task_template manifest: %w", err)
	}

	var tpl Template
	tpl.MaxTokens = m.MaxTokens
	tpl.MaxCompletionTokens = m.MaxCompletionTokens
	tpl.MaxToolRequestTimes = m.MaxToolRequestTimes
	tpl.PlanModeLineThreshold = m.PlanModeLineThreshold
	tpl.PlanModeGroupLineThreshold = m.PlanModeGroupLineThreshold
	tpl.GroupingMinFiles = m.GroupingMinFiles
	tpl.GroupingBundleLineThreshold = m.GroupingBundleLineThreshold
	tpl.MaxReviewRounds = m.MaxReviewRounds

	if tpl.MainTask, err = resolveConversation(m.MainTask); err != nil {
		return nil, fmt.Errorf("MAIN_TASK: %w", err)
	}
	if tpl.PlanTask, err = resolveOptionalConversation(m.PlanTask, "PLAN_TASK"); err != nil {
		return nil, err
	}
	if tpl.MemoryCompressionTask, err = resolveConversation(m.MemoryCompressionTask); err != nil {
		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
}

View on GitHub (pinned to 5cf97d0d15)

Solutions

  1. Open task_template.json, find the MAIN_TASK message whose PromptFile is named in the wrapped error, and correct the path
  2. Confirm the prompt file exists under the package's prompts/ directory and matches the //go:embed pattern (add subdirectories with prompts/** or explicit entries)
  3. Check file-name casing exactly matches the manifest value
  4. Rebuild after fixing, since both the manifest and prompts are embedded

Example fix

// before (task_template.json)
{"MAIN_TASK": {"messages": [{"role": "system", "promptFile": "prompts/main-system.md"}]}}
// after (after renaming file to prompts/main_task_system.md)
{"MAIN_TASK": {"messages": [{"role": "system", "promptFile": "prompts/main_task_system.md"}]}}
Defensive patterns

Strategy: validation

Validate before calling

var m map[string]any
_ = json.Unmarshal(taskTemplateBytes, &m)
main, _ := m["MAIN_TASK"].(map[string]any)
for _, msg := range main["messages"].([]any) {
	pf, _ := msg.(map[string]any)["promptFile"].(string)
	if _, err := template.TaskTemplateFS.ReadFile(pf); err != nil {
		log.Fatalf("MAIN_TASK prompt missing: %s", pf)
	}
}

Try / catch

tpl, err := template.LoadDefault()
if err != nil {
	if strings.Contains(err.Error(), "MAIN_TASK:") {
		return fmt.Errorf("main task prompt file missing from embedded assets — check task_template.json promptFile paths: %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: Calling LoadDefault() when a message in MAIN_TASK of task_template.json names a prompts/<file> that is absent from the embedded FS, or the promptFile value has a wrong path/casing relative to the embed root.

Common situations: Renaming a prompt markdown file without updating task_template.json; embed pattern not covering a new prompts/ subdirectory; typos in the PromptFile field; deleting a prompt as part of cleanup while the manifest still references it.

Related errors


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