{"record":{"id":"b2ed11b0a6cf8022","repo":"alibaba/open-code-review","slug":"model-name-cannot-be-empty","errorCode":null,"errorMessage":"model name cannot be empty","messagePattern":"model name cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/opencodereview/provider_cmd.go","lineNumber":385,"sourceCode":"\t\tConfigPath:     configPath,\n\t\tProviderName:   cfg.Provider,\n\t\tIsCustom:       isCustom,\n\t})\n\tp := tea.NewProgram(m)\n\tfinalModel, err := p.Run()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"TUI error: %w\", err)\n\t}\n\n\tfinal := finalModel.(modelTUIModel)\n\tif final.cancelled {\n\t\tprintWizardCancelled(final.savedInSession, \"Model list changes\")\n\t\treturn nil\n\t}\n\n\tselectedModel := final.selectedModel()\n\tif selectedModel == \"\" {\n\t\treturn fmt.Errorf(\"model name cannot be empty\")\n\t}\n\n\tif isCustom {\n\t\tif cfg.CustomProviders == nil {\n\t\t\tcfg.CustomProviders = make(map[string]ProviderEntry)\n\t\t}\n\t\tentry := cfg.CustomProviders[cfg.Provider]\n\t\tentry.Model = selectedModel\n\t\tentry.Models = ensureModelInList(entry.Models, selectedModel)\n\t\tcfg.CustomProviders[cfg.Provider] = entry\n\t} else {\n\t\tif cfg.Providers == nil {\n\t\t\tcfg.Providers = make(map[string]ProviderEntry)\n\t\t}\n\t\tentry := cfg.Providers[cfg.Provider]\n\t\tentry.Model = selectedModel\n\t\t// Use registry-only list: provider.Models was captured before the TUI and\n\t\t// may include stale entry.Models from add/delete during the session.","sourceCodeStart":367,"sourceCodeEnd":403,"githubUrl":"https://github.com/alibaba/open-code-review/blob/5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f/cmd/opencodereview/provider_cmd.go#L367-L403","documentation":"runConfigModel validates the model chosen in the TUI after the program exits; if final.selectedModel() is empty, it refuses to persist and returns this error. It guards against writing an empty Model value into the config, which would leave the CLI without a usable model for LLM calls.","triggerScenarios":"Finishing the model-selection TUI without a selection (e.g. the model list is empty or the current selection index points at nothing) and not cancelling — finalModel is non-cancelled but selectedModel() returns \"\".","commonSituations":"A custom provider with an empty Models list; a registry/official provider whose model list failed to load; a TUI state bug where selection was never initialized.","solutions":["Add or select a model for the provider before saving (use the provider TUI to add one)","Verify the provider entry has a non-empty Models list in the config file","Check network/registry availability so official provider model lists load correctly","If it persists, cancel out of the wizard instead of confirming with no selection"],"exampleFix":"// before: confirming an empty list in the TUI\nselectedModel := final.selectedModel() // \"\"\n// after: add a model first (custom provider)\n$ ocr config provider add-model my-model\nthen re-run the model picker and confirm a highlighted selection","handlingStrategy":"validation","validationCode":"// before trusting the selection\nif selected := final.selectedModel(); strings.TrimSpace(selected) == \"\" {\n    return fmt.Errorf(\"model name cannot be empty\")\n}","typeGuard":null,"tryCatchPattern":"if err := runConfigModel(...); err != nil {\n    if strings.Contains(err.Error(), \"model name cannot be empty\") {\n        fmt.Fprintln(os.Stderr, \"no model selected — pick a model or cancel with Esc/q\")\n        return nil\n    }\n    return err\n}","preventionTips":["Ensure the provider has at least one model in its Models list before opening the picker","Cancel the wizard (Esc/q) rather than confirming with nothing selected","Verify registry/model-list loading succeeded (network reachable) before the TUI"],"tags":["validation","config","model-selection"],"backgroundTag":"empty-required-value","analyzedSha":"5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f","analyzedAt":"2026-09-02T02:08:09.116Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}