{"record":{"id":"5be18c51a3304c1d","repo":"alibaba/open-code-review","slug":"max-review-rounds-must-not-be-negative","errorCode":null,"errorMessage":"max_review_rounds must not be negative","messagePattern":"max_review_rounds must not be negative","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/config/template/template.go","lineNumber":320,"sourceCode":"\t}\n\tif t.DedupTask != nil {\n\t\tapplyLanguage(t.DedupTask, instruction)\n\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}","sourceCodeStart":302,"sourceCodeEnd":338,"githubUrl":"https://github.com/alibaba/open-code-review/blob/5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f/internal/config/template/template.go#L302-L338","documentation":"Template.Validate allows MaxReviewRounds == 0 (review disabled) but rejects negative values with 'max_review_rounds must not be negative', since a negative round count is meaningless and would corrupt loop logic. It indicates an arithmetic bug or bad manifest data rather than a missing field.","triggerScenarios":"Calling (*Template).Validate() with t.MaxReviewRounds < 0 — e.g. \"MAX_REVIEW_ROUNDS\": -1 in task_template.json, a subtraction underflow when computing rounds from other config, or user-supplied config clamped incorrectly.","commonSituations":"A config UI allowing negative input for review rounds; code like MaxReviewRounds: base - extra that underflows; copy-pasting a template with -1 as a sentinel for 'off' (use 0 instead).","solutions":["Set MaxReviewRounds to 0 to disable review rounds, or a positive number to enable them","Fix the manifest/config source so MAX_REVIEW_ROUNDS is never negative; clamp user input with max(0, value)","Check for arithmetic that can go negative when deriving the value from other settings","Re-run Validate after correction; the check passes for any value >= 0"],"exampleFix":"// before\nrounds := cfg.BaseRounds - cfg.SkippedRounds // can go negative\n// after\nrounds := cfg.BaseRounds - cfg.SkippedRounds\nif rounds < 0 { rounds = 0 }","handlingStrategy":"validation","validationCode":"if tpl.MaxReviewRounds < 0 {\n\treturn fmt.Errorf(\"MaxReviewRounds must be >= 0, got %d\", tpl.MaxReviewRounds)\n}\nif err := tpl.Validate(); err != nil { return err }","typeGuard":null,"tryCatchPattern":"if err := tpl.Validate(); err != nil {\n\tif strings.Contains(err.Error(), \"max_review_rounds must not be negative\") {\n\t\ttpl.MaxReviewRounds = 0 // treat negatives as 'review disabled'\n\t\terr = tpl.Validate()\n\t}\n\tif err != nil { return err }\n}","preventionTips":["Clamp user-supplied round counts with max(0, v)","Use 0, not -1, to mean 'disabled'","Review arithmetic deriving the value from other config for underflow"],"tags":["go","validation","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"}