sigoden/aichat · critical

No available model

Error message

No available model

What it means

Thrown by GlobalConfig::setup_model() during initialization when no model_id is configured AND list_models(self, ModelType::Chat) returns an empty vector — i.e. no usable chat model could be resolved from any provider configuration. The tool cannot proceed without at least one model.

Solutions

  1. Configure at least one provider with a valid API key in config.yaml (or env var), then set `model: <provider>:<model>`.
  2. Set the model explicitly in config.yaml or via the `--model` flag so list_models resolution is bypassed.
  3. Verify provider config with `aichat --list-models` and fix the provider that yields zero models.

Example fix

// config.yaml — before
clients: []
// after
clients:
  - type: openai
    api_key: sk-...
model: openai:gpt-4o
Defensive patterns

Strategy: validation

Validate before calling

let ok = !config.read().model_id.is_empty() || !list_models(&config, ModelType::Chat).is_empty(); if !ok { eprintln!("configure a provider and model in config.yaml"); }

Try / catch

if let Err(e) = config.write().setup_model() { if e.to_string() == "No available model" { eprintln!("Set `model:` and provider api_key in config.yaml"); std::process::exit(1); } return Err(e.into()); }

Prevention

When it happens

Trigger: Starting aichat (REPL/CMD/serve startup calls setup_model) with: no `model` in config.yaml, all providers missing/invalid API keys so no models register, or provider config present but exposing zero chat models.

Common situations: Fresh install without any provider configured; API keys unset in env/config so provider init is skipped; typo'd provider name in config.yaml; all providers filtered out by platform restrictions.

Understand the failure class

Background: "missing required config value" errors: why libraries refuse to start when a configuration key is empty, unset, or blank — this error's family across 48 libraries.

Related errors


AI-assisted analysis of sigoden/aichat@82976d349a (2026-09-09). Data as JSON: /api/errors/61e8858520e06124. Report an issue: GitHub.

Appendix: source

Thrown at src/config/mod.rs:2393

        if let Some(Some(v)) = read_env_bool(&get_env_name("save_shell_history")) {
            self.save_shell_history = v;
        }
        if let Some(v) = read_env_value::<String>(&get_env_name("sync_models_url")) {
            self.sync_models_url = v;
        }
    }

    fn load_functions(&mut self) -> Result<()> {
        self.functions = Functions::init(&Self::functions_file())?;
        Ok(())
    }

    fn setup_model(&mut self) -> Result<()> {
        let mut model_id = self.model_id.clone();
        if model_id.is_empty() {
            let models = list_models(self, ModelType::Chat);
            if models.is_empty() {
                bail!("No available model");
            }
            model_id = models[0].id()
        };
        self.set_model(&model_id)?;
        self.model_id = model_id;
        Ok(())
    }

    fn setup_document_loaders(&mut self) {
        [("pdf", "pdftotext $1 -"), ("docx", "pandoc --to plain $1")]
            .into_iter()
            .for_each(|(k, v)| {
                let (k, v) = (k.to_string(), v.to_string());
                self.document_loaders.entry(k).or_insert(v);
            });
    }

    fn setup_user_agent(&mut self) {

View on GitHub (pinned to 82976d349a)