alibaba/open-code-review · error
scan template MAIN_TASK is missing or empty
Error message
scan template MAIN_TASK is missing or empty
What it means
Agent.Run refuses to start the full-scan pipeline when the scan template's MAIN_TASK prompt has no messages. The MAIN_TASK template drives the per-file review loop, so an empty template means the scan cannot produce meaningful requests; the error fails fast before any enumeration or LLM calls.
Source
Thrown at internal/scan/agent.go:304
}
func scanItemFingerprint(it model.ScanItem) string {
sum := sha256.Sum256([]byte(session.ReviewModeFullScan + "\x00" + it.Path + "\x00" + it.Content))
return fmt.Sprintf("%x", sum)
}
func resumedFromSession(resume *session.ResumeState) string {
if resume == nil {
return ""
}
return resume.SessionID
}
// Run executes the full-scan pipeline: enumerate → filter → token-filter →
// dispatch one subtask per file → collect comments.
func (a *Agent) Run(ctx context.Context) ([]model.LlmComment, error) {
if len(a.args.Template.MainTask.Messages) == 0 {
return nil, fmt.Errorf("scan template MAIN_TASK is missing or empty")
}
// Base prompt-cache affinity key for any LLM request in this run that a
// task doesn't re-scope. Each task conversation (plan, per-file main
// loop, dedup, summary) refines it with llm.SessionTaskKey where it
// starts, so affinity keys stay per-conversation — the granularity
// provider prompt caches actually reuse prefixes at.
ctx = llm.ContextWithSessionKey(ctx, a.SessionID())
ctx, scanSpan := telemetry.StartSpan(ctx, "scan.enumerate")
provider := NewProvider(a.args.RepoDir, a.args.Paths, a.args.GitRunner, a.args.MaxFileSizeBytes)
items, err := provider.Enumerate(ctx)
if err != nil {
scanSpan.End()
return nil, fmt.Errorf("enumerate files: %w", err)
}
telemetry.SetAttr(scanSpan, "files.enumerated", len(items))
scanSpan.End()View on GitHub (pinned to 5cf97d0d15)
Solutions
- Provide a template whose MAIN_TASK section defines at least one message, or drop the custom template override to use the built-in default
- Check the template key spelling — it must be MAIN_TASK (uppercase) with a non-empty messages list
- Regenerate/refresh a custom template that was authored against an older OCR version
Example fix
# before (custom template)
[PLAN_TASK]
messages = [...]
# after — add the required section
[MAIN_TASK]
messages = [{ role = "user", content = "Review this file: {{.Content}}" }] Defensive patterns
Strategy: validation
Validate before calling
// validate the template before running the scan
if len(args.Template.MainTask.Messages) == 0 {
return fmt.Errorf("custom template must define a non-empty MAIN_TASK section")
} Try / catch
comments, err := agent.Run(ctx)
if err != nil && strings.Contains(err.Error(), "MAIN_TASK is missing or empty") {
// fall back to the built-in template or fix the custom template file
} Prevention
- When supplying a custom template, always include MAIN_TASK with at least one message
- Re-validate custom templates after OCR upgrades in case keys changed
- Smoke-test custom templates on a single-file scan before full runs
When it happens
Trigger: Running a scan where the resolved scan template (built-in or custom via template config) has an empty or missing MAIN_TASK section — e.g. a custom template file defining only other task keys, or a template path pointing at the wrong file.
Common situations: Pointing --template/custom template config at a file that defines PLAN_TASK/DEDUP_TASK but omits MAIN_TASK; an older template format after an OCR upgrade renamed the key; an empty template file created by mistake.
Related errors
- load scan template: %w
- invalid config: %w
- max_tokens must be positive
- max_tool_request_times must be positive
- main_task.messages must not be empty
AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02).
Data as JSON: /api/errors/09d51cff704d799f.
Report an issue: GitHub.