{"record":{"id":"37b92eff45765af7","repo":"alibaba/open-code-review","slug":"timeout-sec-must-be-non-negative-got-d","errorCode":null,"errorMessage":"timeout_sec must be non-negative, got %d","messagePattern":"timeout_sec must be non-negative, got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/llm/resolver.go","lineNumber":226,"sourceCode":"\tsec, err := strconv.Atoi(raw)\n\tif err != nil {\n\t\treturn 0, false, fmt.Errorf(\"OCR_LLM_TIMEOUT must be an integer (seconds): %w\", err)\n\t}\n\td, err := validateTimeoutSec(sec)\n\tif err != nil {\n\t\treturn 0, false, fmt.Errorf(\"OCR_LLM_TIMEOUT: %w\", err)\n\t}\n\treturn d, true, nil\n}\n\n// validateTimeoutSec converts a config-file timeout (in seconds) to time.Duration.\n// Returns 0 for zero input (use default). Rejects negative values and overflow.\nfunc validateTimeoutSec(sec int) (time.Duration, error) {\n\tif sec == 0 {\n\t\treturn 0, nil\n\t}\n\tif sec < 0 {\n\t\treturn 0, fmt.Errorf(\"timeout_sec must be non-negative, got %d\", sec)\n\t}\n\t// Guard against overflow: time.Duration is int64 nanoseconds.\n\tmaxSec := int64(math.MaxInt64 / int64(time.Second))\n\tif int64(sec) > maxSec {\n\t\treturn 0, fmt.Errorf(\"timeout_sec %d overflows time.Duration (max %d)\", sec, maxSec)\n\t}\n\treturn time.Duration(sec) * time.Second, nil\n}\n\n// errBedrockNotConfigurable explains why the two url+token strategies reject the\n// bedrock protocol. Both describe a single HTTP endpoint and carry no place for\n// a region or a profile, and bedrock uses neither the url nor the token they do\n// carry. Accepting the value would switch transports and silently ignore the\n// rest of the block, so it is refused at the point it is read.\nfunc errBedrockNotConfigurable(key string) error {\n\treturn 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\\\")\",\n\t\tkey, ProtocolAnthropicBedrock)\n}","sourceCodeStart":208,"sourceCodeEnd":244,"githubUrl":"https://github.com/alibaba/open-code-review/blob/5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f/internal/llm/resolver.go#L208-L244","documentation":"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).","triggerScenarios":"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.","commonSituations":"Using a negative number to mean \"disable timeout\" (not supported); a sign typo when editing config.json by hand.","solutions":["Change timeout_sec to a non-negative integer in the config section","Use 0 to mean the default timeout, or omit the key entirely","If a shorter cap is desired, set a positive value in seconds"],"exampleFix":"// before\n\"timeout_sec\": -1\n// after\n\"timeout_sec\": 300","handlingStrategy":"validation","validationCode":"func checkTimeoutSec(sec int) error {\n    if sec < 0 {\n        return fmt.Errorf(\"timeout_sec must be non-negative, got %d\", sec)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"timeout_sec must be non-negative\") {\n    return fmt.Errorf(\"fix timeout_sec in config (use >=0): %w\", err)\n}","preventionTips":["Use 0 or omit the key for the default; never negatives","Lint config.json for negative numeric fields","Clamp computed timeouts to >= 0 before writing config"],"tags":["config","validation","timeout"],"backgroundTag":"config-value-out-of-range","analyzedSha":"5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f","analyzedAt":"2026-09-02T02:08:09.116Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}