{"record":{"id":"9af8e036ed06c92b","repo":"alibaba/open-code-review","slug":"invalid-config-w","errorCode":null,"errorMessage":"invalid config: %w","messagePattern":"invalid config: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/opencodereview/shared.go","lineNumber":100,"sourceCode":"//\n// requireGit=true fails fast when the directory is not a git repo (review\n// path: diff concept requires git). requireGit=false allows non-git\n// directories (scan path: provider falls back to filepath.Walk).\n//\n// contentRef is the git ref whose file content the rule resolver should\n// inspect when disambiguating ambiguous extensions — derive it via\n// tool.ParseReviewMode(from, to, commit).RefValue(to, commit). Pass \"\" to\n// read the working tree, which is what scan wants.\nfunc loadCommonContext(repoDirInput, rulePath, contentRef string, maxTools, maxGitProcs int, requireGit bool) (*commonContext, error) {\n\ttpl, err := template.LoadDefault()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"load default template: %w\", err)\n\t}\n\tif maxTools > tpl.MaxToolRequestTimes {\n\t\ttpl.MaxToolRequestTimes = maxTools\n\t}\n\tif err := tpl.Validate(); err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid config: %w\", err)\n\t}\n\n\trepoDir, isGit, err := resolveWorkingDir(repoDirInput, requireGit)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Built before the resolver: the sniffer reads file content at contentRef\n\t// through this limiter.\n\tgitRunner := gitcmd.New(maxGitProcs)\n\n\tresolver, fileFilter, err := rules.NewResolver(repoDir, rulePath, rules.ResolverOptions{\n\t\tRef:    contentRef,\n\t\tRunner: gitRunner,\n\t})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"load rules: %w\", err)\n\t}","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/alibaba/open-code-review/blob/5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f/cmd/opencodereview/shared.go#L82-L118","documentation":"After loading the default template (and applying any maxTools override), loadCommonContext runs tpl.Validate(); a failure is wrapped as 'invalid config'. This means the task template struct itself is inconsistent — invalid limits, missing required fields — i.e. the effective configuration cannot pass invariant checks.","triggerScenarios":"Commands built on loadCommonContext when the embedded template (possibly mutated by a maxTools override) fails Validate(), or in tests injecting a template with invalid field values.","commonSituations":"Local builds with hand-edited template defaults; tests constructing CommonContext/preview with zero or negative limits; maxTools override interacting badly with a template that has invalid other fields.","solutions":["Rebuild from a clean tree so the embedded template is pristine","Check what Validate() reports (unwrap the %w) and fix the offending field (e.g. non-positive limits)","In tests, populate all required template fields before calling paths that validate it"],"exampleFix":"// before\ntpl := &template.Template{} // empty -> invalid config\n// after\ntpl := template.Default(); tpl.MaxToolRequestTimes = maxTools // then Validate()","handlingStrategy":"validation","validationCode":"// validate any template you construct or override\nif err := tpl.Validate(); err != nil {\n    return fmt.Errorf(\"template invalid before use: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := tpl.Validate(); err != nil {\n    return nil, fmt.Errorf(\"invalid config: %w\", err)\n}","preventionTips":["Never hand-edit embedded template defaults; use supported flags/overrides","Call Validate() immediately after constructing or mutating a template in tests","Keep template invariants (positive limits) documented for contributors"],"tags":["go","config","validation","template"],"backgroundTag":"schema-validation-failed","analyzedSha":"5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f","analyzedAt":"2026-09-02T02:08:09.116Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}