{"record":{"id":"ecb39c21ecad1d61","repo":"alibaba/open-code-review","slug":"provider-and-model-are-required","errorCode":null,"errorMessage":"provider and model are required","messagePattern":"provider and model are required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/opencodereview/provider_cmd.go","lineNumber":262,"sourceCode":"\tif apiKey != \"\" || strings.TrimSpace(apiKeyCmd) != \"\" {\n\t\treturn nil\n\t}\n\tswitch {\n\tcase isPreset && preset.AmbientAuth:\n\t\treturn nil\n\tcase isPreset && preset.EnvVar != \"\":\n\t\tif os.Getenv(preset.EnvVar) == \"\" {\n\t\t\treturn fmt.Errorf(\"API key is required for provider %s (configure it, set providers.%s.api_key_cmd, or set $%s)\", providerName, providerName, preset.EnvVar)\n\t\t}\n\t\treturn nil\n\tdefault:\n\t\treturn fmt.Errorf(\"API key is required for provider %s (configure it or set providers.%s.api_key_cmd)\", providerName, providerName)\n\t}\n}\n\nfunc applyOfficialProviderConfig(configPath string, cfg *Config, result providerTUIResult) error {\n\tif result.provider == \"\" {\n\t\treturn fmt.Errorf(\"provider and model are required\")\n\t}\n\tmodel := result.resolvedModel()\n\tif model == \"\" {\n\t\treturn fmt.Errorf(\"provider and model are required\")\n\t}\n\n\tpreset, isPreset := llm.LookupProvider(result.provider)\n\n\tif err := checkAPIKeyRequirement(result.provider, result.apiKey, cfg.Providers[result.provider].APIKeyCmd, preset, isPreset); err != nil {\n\t\treturn err\n\t}\n\n\tif cfg.Providers == nil {\n\t\tcfg.Providers = make(map[string]ProviderEntry)\n\t}\n\n\tentry := cfg.Providers[result.provider]\n\tentry.Model = model","sourceCodeStart":244,"sourceCodeEnd":280,"githubUrl":"https://github.com/alibaba/open-code-review/blob/5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f/cmd/opencodereview/provider_cmd.go#L244-L280","documentation":"applyOfficialProviderConfig requires both a provider name and a model before persisting an official provider selection. When the provider name is empty, the wizard produced no usable selection at all, so the function returns the combined 'provider and model are required' message.","triggerScenarios":"applyOfficialProviderConfig is entered with result.provider == \"\" — the wizard result carries no provider; covered by TestApplyOfficialProviderConfig_MissingFields.","commonSituations":"Cancelling the official-provider wizard; a non-interactive path that builds providerTUIResult without setting provider; regression in the TUI that clears the selection before apply.","solutions":["Complete the provider wizard and select a provider before saving","Ensure providerTUIResult.provider is set when constructing the result programmatically","Treat wizard cancellation as a clean exit rather than calling apply"],"exampleFix":"// before\nresult := providerTUIResult{} // provider empty\n// after\nresult := providerTUIResult{provider: \"openai\", model: \"gpt-4o\"}\nerr := applyOfficialProviderConfig(path, cfg, result)","handlingStrategy":"validation","validationCode":"if result.provider == \"\" {\n    return errors.New(\"no provider selected; rerun 'ocr config provider'\")\n}\napplyOfficialProviderConfig(configPath, cfg, result)","typeGuard":"func hasProviderSelection(r providerTUIResult) bool { return r.provider != \"\" }","tryCatchPattern":null,"preventionTips":["Exit cleanly on wizard cancel instead of applying an empty result","Validate the TUI result struct in tests before calling apply"],"tags":["config","cli","validation","provider"],"backgroundTag":"missing-required-argument","analyzedSha":"5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f","analyzedAt":"2026-09-02T02:08:09.116Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}