{"record":{"id":"c38bd498bdd913dd","repo":"alibaba/open-code-review","slug":"main-task-messages-must-not-be-empty","errorCode":null,"errorMessage":"main_task.messages must not be empty","messagePattern":"main_task\\.messages must not be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/config/template/template.go","lineNumber":323,"sourceCode":"\t}\n\tif t.ProjectSummaryTask != nil {\n\t\tapplyLanguage(t.ProjectSummaryTask, instruction)\n\t}\n\tapplyLanguage(&t.MemoryCompressionTask, instruction)\n}\n\nfunc (t *Template) Validate() error {\n\tif t.MaxTokens <= 0 {\n\t\treturn fmt.Errorf(\"max_tokens must be positive\")\n\t}\n\tif t.MaxToolRequestTimes <= 0 {\n\t\treturn fmt.Errorf(\"max_tool_request_times must be positive\")\n\t}\n\tif t.MaxReviewRounds < 0 {\n\t\treturn fmt.Errorf(\"max_review_rounds must not be negative\")\n\t}\n\tif len(t.MainTask.Messages) == 0 {\n\t\treturn fmt.Errorf(\"main_task.messages must not be empty\")\n\t}\n\treturn nil\n}\n\n// Validate checks that a ScanTemplate has the minimum fields populated.\nfunc (t *ScanTemplate) Validate() error {\n\tif t.MaxTokens <= 0 {\n\t\treturn fmt.Errorf(\"scan: max_tokens must be positive\")\n\t}\n\tif t.MaxToolRequestTimes <= 0 {\n\t\treturn fmt.Errorf(\"scan: max_tool_request_times must be positive\")\n\t}\n\tif len(t.MainTask.Messages) == 0 {\n\t\treturn fmt.Errorf(\"scan: main_task.messages must not be empty\")\n\t}\n\treturn nil\n}\n","sourceCodeStart":305,"sourceCodeEnd":341,"githubUrl":"https://github.com/alibaba/open-code-review/blob/5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f/internal/config/template/template.go#L305-L341","documentation":"Template.Validate requires the main task conversation to contain at least one message; a Template with no MAIN_TASK messages has nothing to send to the LLM, so Validate returns 'main_task.messages must not be empty'. This is thrown for programmatically built templates or manifests where MAIN_TASK.messages is an empty array or the field is absent.","triggerScenarios":"Calling (*Template).Validate() with len(t.MainTask.Messages) == 0 — e.g. task_template.json with \"MAIN_TASK\": {\"messages\": []}, a template literal with MainTask unset, or resolveConversation failing silently upstream is impossible here (it errors), so this is purely an emptiness check.","commonSituations":"Authoring a custom template manifest and forgetting to add messages; truncating the JSON during editing; constructing a Template in tests/injection code and skipping MainTask; a generation script that emitted an empty messages array.","solutions":["Add at least one message (typically a system prompt referencing a promptFile) to MAIN_TASK in task_template.json and rebuild","When constructing Template in Go, populate MainTask.Messages from resolveConversation or literal ChatMessage values before Validate","Guard any script that generates the manifest to fail if it would emit an empty messages array","Run the package tests (TestValidate_*) after editing to confirm the manifest still validates"],"exampleFix":"// before (task_template.json)\n{\"MAIN_TASK\": {\"messages\": []}}\n// after\n{\"MAIN_TASK\": {\"messages\": [{\"role\": \"system\", \"promptFile\": \"prompts/main_system.md\"}]}}","handlingStrategy":"validation","validationCode":"if len(tpl.MainTask.Messages) == 0 {\n\treturn fmt.Errorf(\"MainTask must have at least one message before Validate\")\n}\nif err := tpl.Validate(); err != nil { return err }","typeGuard":"func hasMainTaskMessages(t *template.Template) bool {\n\treturn t != nil && len(t.MainTask.Messages) > 0\n}","tryCatchPattern":"if err := tpl.Validate(); err != nil {\n\tif strings.Contains(err.Error(), \"main_task.messages must not be empty\") {\n\t\treturn fmt.Errorf(\"template was built without MAIN_TASK messages; populate MainTask via resolveConversation or LoadDefault\")\n\t}\n\treturn err\n}","preventionTips":["Prefer LoadDefault/LoadScanDefault over hand-built Template literals","Fail manifest generators when messages arrays would be empty","Keep at least one system message in MAIN_TASK when trimming templates"],"tags":["go","validation","template","config"],"backgroundTag":"invalid-config-value","analyzedSha":"5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f","analyzedAt":"2026-09-02T02:08:09.116Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}