alibaba/open-code-review · error

invalid scan template: %w

Error message

invalid scan template: %w

What it means

After loading the embedded scan template, `ocr scan` calls ScanTemplate.Validate(). If the template's own invariants are violated (e.g. non-positive MaxTokens or MaxToolRequestTimes, invalid budget/prompt fields), the CLI wraps the error as "invalid scan template: %w" and aborts before scanning. Like [130], the template is embedded, so this usually indicates a bad release artifact rather than user configuration.

Source

Thrown at cmd/opencodereview/scan_cmd.go:136

			retErr = errors.Join(retErr, fmt.Errorf("close output file: %w", cerr))
		}
	}()

	cc, err := loadCommonContext(opts.repoDir, opts.rulePath, "", opts.maxTools, opts.maxGitProcs, false)
	if err != nil {
		return err
	}
	applyCLIExcludes(cc, splitPaths(opts.excludes))

	// scan owns its own template (scan_template.json) independent from the
	// diff-review template loaded by loadCommonContext above. Apply --max-tools
	// as an "only raise" override to the scan template's per-file budget.
	scanTpl, err := template.LoadScanDefault()
	if err != nil {
		return fmt.Errorf("load scan template: %w", err)
	}
	if err := scanTpl.Validate(); err != nil {
		return fmt.Errorf("invalid scan template: %w", err)
	}
	if opts.maxTools > scanTpl.MaxToolRequestTimes {
		scanTpl.MaxToolRequestTimes = opts.maxTools
	}
	if opts.batch != "" {
		// CLI override of BATCH_STRATEGY; validated downstream by parseBatchStrategy
		// (unknown values silently fall back to "none").
		scanTpl.BatchStrategy = opts.batch
	}
	// Token budget: --max-tokens-budget overrides the template value when set.
	budget := scanTpl.MaxTokensBudget
	if opts.maxTokensBudget > 0 {
		budget = int64(opts.maxTokensBudget)
	}

	scanPaths := splitPaths(opts.paths)

	if opts.preview {

View on GitHub (pinned to 5cf97d0d15)

Solutions

  1. Rebuild/reinstall ocr from an official source so the embedded scan_template.json passes Validate().
  2. Read the wrapped message — the inner text names the violated field (e.g. "max_tokens must be positive") and fix it in scan_template.json if you own the checkout.
  3. Check whether a --max-tools or environment override in your wrapper script is interacting with a patched template; test with a stock binary.

Example fix

// before (hand-edited template in a fork)
"max_tool_request_times": 0
// after
"max_tool_request_times": 40
Defensive patterns

Strategy: validation

Validate before calling

tpl, err := template.LoadScanDefault()
if err == nil {
    err = tpl.Validate() // surfaces "max_tokens must be positive" etc.
}
if err != nil {
    return err // run nothing until template is valid
}

Type guard

func templateValid(t *template.ScanTemplate) bool {
    return t != nil && t.MaxTokens > 0 && t.MaxToolRequestTimes > 0
}

Try / catch

if err := scanTpl.Validate(); err != nil {
    log.Fatalf("invalid scan template: %v", err) // inner text names the bad field
}

Prevention

When it happens

Trigger: Running `ocr scan` (with or without --max-tools/--batch overrides applied later) when the parsed ScanTemplate fails Validate() — e.g. MaxTokens <= 0 or MaxToolRequestTimes <= 0 baked into the embedded scan_template.json.

Common situations: Using a forked or patched binary where scan_template.json was hand-edited with a zero/negative budget; a regression release where template validation constants drifted.

Related errors


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