{"record":{"id":"8db6af7bd53eea4e","repo":"alibaba/open-code-review","slug":"scan-main-task-messages-must-not-be-empty","errorCode":null,"errorMessage":"scan: main_task.messages must not be empty","messagePattern":"scan: main_task\\.messages must not be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/config/template/template.go","lineNumber":337,"sourceCode":"\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\n// LlmConversation is a preset prompt with settings.\ntype LlmConversation struct {\n\tMessages []ChatMessage `json:\"messages\"`\n}\n\n// ChatMessage represents a single message in a conversation.\ntype ChatMessage struct {\n\tRole    string `json:\"role\"`\n\tContent string `json:\"content\"`\n}\n","sourceCodeStart":319,"sourceCodeEnd":352,"githubUrl":"https://github.com/alibaba/open-code-review/blob/5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f/internal/config/template/template.go#L319-L352","documentation":"ScanTemplate.Validate rejects a template whose MainTask.Messages slice is empty. The main task conversation must contain at least one message (typically the system/user prompt driving the scan); an empty list means the LLM would be invoked with nothing to do. Validation fails fast before any request is made.","triggerScenarios":"Calling Validate() on a ScanTemplate where MainTask is the zero value or where the messages array in the config file is empty ([]) or absent.","commonSituations":"Template files with main_task section omitted entirely; a prompt refactoring that emptied the messages list; deserializing a template where the messages key is misspelled so nothing is populated.","solutions":["Add at least one message (role + content) under main_task.messages in the template","Check the template file for a misspelled or misplaced messages key so it actually unmarshals","Copy a known-good template and adapt the prompt instead of starting from an empty struct"],"exampleFix":"// before\nMainTask: LlmTask{ Settings: settings } // no messages\n// after\nMainTask: LlmTask{ Settings: settings, Messages: []Message{{Role: \"user\", Content: scanPrompt}} }","handlingStrategy":"validation","validationCode":"func hasMessages(t template.ScanTemplate) bool { return len(t.MainTask.Messages) > 0 }","typeGuard":null,"tryCatchPattern":"if err := t.Validate(); err != nil { return fmt.Errorf(\"invalid scan template: %w\", err) }","preventionTips":["Never commit template files with empty main_task.messages","Add a CI check that validates every shipped template with Validate()","Start from a known-good template when authoring new prompts"],"tags":["config","validation","prompt"],"backgroundTag":"invalid-config-value","analyzedSha":"5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f","analyzedAt":"2026-09-02T02:08:09.116Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}