alibaba/open-code-review · error

max_tool_request_times must be positive

Error message

max_tool_request_times must be positive

What it means

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.

Source

Thrown at internal/config/template/template.go:317

	applyLanguage(&t.MainTask, instruction)
	if t.PlanTask != nil {
		applyLanguage(t.PlanTask, instruction)
	}
	if t.DedupTask != nil {
		applyLanguage(t.DedupTask, instruction)
	}
	if t.ProjectSummaryTask != nil {
		applyLanguage(t.ProjectSummaryTask, instruction)
	}
	applyLanguage(&t.MemoryCompressionTask, instruction)
}

func (t *Template) Validate() error {
	if t.MaxTokens <= 0 {
		return fmt.Errorf("max_tokens must be positive")
	}
	if t.MaxToolRequestTimes <= 0 {
		return fmt.Errorf("max_tool_request_times must be positive")
	}
	if t.MaxReviewRounds < 0 {
		return fmt.Errorf("max_review_rounds must not be negative")
	}
	if len(t.MainTask.Messages) == 0 {
		return fmt.Errorf("main_task.messages must not be empty")
	}
	return nil
}

// Validate checks that a ScanTemplate has the minimum fields populated.
func (t *ScanTemplate) Validate() error {
	if t.MaxTokens <= 0 {
		return fmt.Errorf("scan: max_tokens must be positive")
	}
	if t.MaxToolRequestTimes <= 0 {
		return fmt.Errorf("scan: max_tool_request_times must be positive")
	}

View on GitHub (pinned to 5cf97d0d15)

Solutions

  1. Set MaxToolRequestTimes to a positive bound (e.g. 10) on the Template before Validate
  2. Add "MAX_TOOL_REQUEST_TIMES": <n> (n > 0) to the manifest JSON and rebuild if loaded from task_template.json
  3. If tools should be unavailable, configure the tool set rather than setting the budget to 0
  4. Call Validate() right after template construction to catch the missing field early

Example fix

// before (task_template.json)
{"MAX_TOKENS": 4096, "MAIN_TASK": {...}}
// after
{"MAX_TOKENS": 4096, "MAX_TOOL_REQUEST_TIMES": 10, "MAIN_TASK": {...}}
Defensive patterns

Strategy: validation

Validate before calling

if tpl.MaxToolRequestTimes <= 0 {
	return fmt.Errorf("MaxToolRequestTimes must be > 0 before Validate, got %d", tpl.MaxToolRequestTimes)
}
if err := tpl.Validate(); err != nil { return err }

Try / catch

if err := tpl.Validate(); err != nil {
	if strings.Contains(err.Error(), "max_tool_request_times must be positive") {
		tpl.MaxToolRequestTimes = 10
		err = tpl.Validate()
	}
	if err != nil { return err }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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).

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02). Data as JSON: /api/errors/a22caf5a1ba6117a. Report an issue: GitHub.