{"record":{"id":"a22caf5a1ba6117a","repo":"alibaba/open-code-review","slug":"max-tool-request-times-must-be-positive","errorCode":null,"errorMessage":"max_tool_request_times must be positive","messagePattern":"max_tool_request_times must be positive","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/config/template/template.go","lineNumber":317,"sourceCode":"\tapplyLanguage(&t.MainTask, instruction)\n\tif t.PlanTask != nil {\n\t\tapplyLanguage(t.PlanTask, instruction)\n\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}","sourceCodeStart":299,"sourceCodeEnd":335,"githubUrl":"https://github.com/alibaba/open-code-review/blob/5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f/internal/config/template/template.go#L299-L335","documentation":"Template.Validate requires MaxToolRequestTimes > 0 because it bounds how many tool-call rounds an agent session may perform; zero would disable tool use entirely and negative values are meaningless, so Validate rejects them with 'max_tool_request_times must be positive'. It surfaces when a Template was built or loaded without this knob set.","triggerScenarios":"Calling (*Template).Validate() with t.MaxToolRequestTimes <= 0 — usually a manifest JSON missing MAX_TOOL_REQUEST_TIMES or a manually constructed Template leaving the field at its zero value.","commonSituations":"Writing a custom task_template.json and omitting MAX_TOOL_REQUEST_TIMES; partial field copying in template-construction code; intentionally setting it to 0 to 'disable tools' (which is rejected instead — remove the tools instead).","solutions":["Set MaxToolRequestTimes to a positive bound (e.g. 10) on the Template before Validate","Add \"MAX_TOOL_REQUEST_TIMES\": <n> (n > 0) to the manifest JSON and rebuild if loaded from task_template.json","If tools should be unavailable, configure the tool set rather than setting the budget to 0","Call Validate() right after template construction to catch the missing field early"],"exampleFix":"// before (task_template.json)\n{\"MAX_TOKENS\": 4096, \"MAIN_TASK\": {...}}\n// after\n{\"MAX_TOKENS\": 4096, \"MAX_TOOL_REQUEST_TIMES\": 10, \"MAIN_TASK\": {...}}","handlingStrategy":"validation","validationCode":"if tpl.MaxToolRequestTimes <= 0 {\n\treturn fmt.Errorf(\"MaxToolRequestTimes must be > 0 before Validate, got %d\", tpl.MaxToolRequestTimes)\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_tool_request_times must be positive\") {\n\t\ttpl.MaxToolRequestTimes = 10\n\t\terr = tpl.Validate()\n\t}\n\tif err != nil { return err }\n}","preventionTips":["Never use 0 as a 'disable tools' sentinel; configure the tool set instead","Copy all manifest numeric fields when converting templateManifest to Template","Run TestValidate-style tests after template changes"],"tags":["go","validation","config","template"],"backgroundTag":"invalid-config-value","analyzedSha":"5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f","analyzedAt":"2026-09-02T02:08:09.116Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}