alibaba/open-code-review · error

timeout_sec must be non-negative, got %d

Error message

timeout_sec must be non-negative, got %d

What it means

validateTimeoutSec converts a config-file timeout_sec value into time.Duration. Zero is allowed (means "use default"); negative values are rejected with this message. It is shared by OCR_LLM_TIMEOUT parsing and the config-file provider/llm sections (tryProviderConfig, tryLegacyLlmConfig).

Source

Thrown at internal/llm/resolver.go:226

	sec, err := strconv.Atoi(raw)
	if err != nil {
		return 0, false, fmt.Errorf("OCR_LLM_TIMEOUT must be an integer (seconds): %w", err)
	}
	d, err := validateTimeoutSec(sec)
	if err != nil {
		return 0, false, fmt.Errorf("OCR_LLM_TIMEOUT: %w", err)
	}
	return d, true, nil
}

// validateTimeoutSec converts a config-file timeout (in seconds) to time.Duration.
// Returns 0 for zero input (use default). Rejects negative values and overflow.
func validateTimeoutSec(sec int) (time.Duration, error) {
	if sec == 0 {
		return 0, nil
	}
	if sec < 0 {
		return 0, fmt.Errorf("timeout_sec must be non-negative, got %d", sec)
	}
	// Guard against overflow: time.Duration is int64 nanoseconds.
	maxSec := int64(math.MaxInt64 / int64(time.Second))
	if int64(sec) > maxSec {
		return 0, fmt.Errorf("timeout_sec %d overflows time.Duration (max %d)", sec, maxSec)
	}
	return time.Duration(sec) * time.Second, nil
}

// errBedrockNotConfigurable explains why the two url+token strategies reject the
// bedrock protocol. Both describe a single HTTP endpoint and carry no place for
// a region or a profile, and bedrock uses neither the url nor the token they do
// carry. Accepting the value would switch transports and silently ignore the
// rest of the block, so it is refused at the point it is read.
func errBedrockNotConfigurable(key string) error {
	return fmt.Errorf("%s cannot be %q: bedrock derives its host from aws_region and signs with the AWS credential chain, so it has no use for a url or a token; configure it as a provider instead (\"provider\": \"bedrock\")",
		key, ProtocolAnthropicBedrock)
}

View on GitHub (pinned to 5cf97d0d15)

Solutions

  1. Change timeout_sec to a non-negative integer in the config section
  2. Use 0 to mean the default timeout, or omit the key entirely
  3. If a shorter cap is desired, set a positive value in seconds

Example fix

// before
"timeout_sec": -1
// after
"timeout_sec": 300
Defensive patterns

Strategy: validation

Validate before calling

func checkTimeoutSec(sec int) error {
    if sec < 0 {
        return fmt.Errorf("timeout_sec must be non-negative, got %d", sec)
    }
    return nil
}

Try / catch

if err != nil && strings.Contains(err.Error(), "timeout_sec must be non-negative") {
    return fmt.Errorf("fix timeout_sec in config (use >=0): %w", err)
}

Prevention

When it happens

Trigger: Setting "timeout_sec": -5 in a providers/custom_providers or legacy llm section of config.json, or OCR_LLM_TIMEOUT=-5 in the environment; also hit by <anonymous> callers of validateTimeoutSec.

Common situations: Using a negative number to mean "disable timeout" (not supported); a sign typo when editing config.json by hand.

Understand the failure class

Related errors


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