sigoden/aichat · error · anyhow::Error
{err_msg}
Error message
{err_msg} What it means
In src/config/mod.rs config-loading code, a per-client (or section) configuration value failed validation; the message is dynamic (`{err_msg}`), optionally augmented with the offending value and a note that an exact location cannot be pinpointed. The error is re-thrown via `anyhow!` and layered with context naming the failing field.
Solutions
- Read the full error chain (context) to find which config section failed.
- Fix the offending client entry's value/type in the config file.
- Compare against the documented config schema for your version after an upgrade.
- Temporarily simplify the config to bisect which entry is invalid.
Example fix
// before (config.yaml)
clients:
- type: openai
api_key: 12345 # wrong type
// after
clients:
- type: openai
api_key: "sk-..." Defensive patterns
Strategy: validation
Validate before calling
// Pre-validate config parses before use
serde_yaml::from_str::<Config>(&std::fs::read_to_string("config.yaml")?)
.map_err(|e| eprintln!("config invalid: {e}")); Try / catch
// Rust
match load_config() {
Err(e) => {
for cause in e.chain() { eprintln!("caused by: {cause}"); }
}
Ok(c) => c,
} Prevention
- Keep config files version-controlled and schema-checked.
- Re-check client entries after CLI upgrades (schema drift).
- Use quoted strings for keys/tokens to avoid type coercion.
- Read the whole anyhow error chain, not just the top message.
When it happens
Trigger: Deserializing/validating a config file where a `clients` entry (or similar section) has an invalid value; the raw parse error is converted into `err_msg` and, when the value can't be located, appended with "(Sorry for being unable to provide an exact location)".
Common situations: Hand-edited config.yaml with a wrong type or unknown enum for a client field; copied config from another tool version; schema drift after upgrading the CLI.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Invalid wrap value
- No models
- Unknown client
- Unknown model
- Please enable function calling before using the agent.
AI-assisted analysis of sigoden/aichat@82976d349a (2026-09-09).
Data as JSON: /api/errors/0795436bf4955f3b.
Report an issue: GitHub.
Appendix: source
Thrown at src/config/mod.rs:2218
fn load_from_file(config_path: &Path) -> Result<Self> {
let err = || format!("Failed to load config at '{}'", config_path.display());
let content = read_to_string(config_path).with_context(err)?;
let config: Self = serde_yaml::from_str(&content)
.map_err(|err| {
let err_msg = err.to_string();
let err_msg = if err_msg.starts_with(&format!("{CLIENTS_FIELD}: ")) {
// location is incorrect, get rid of it
err_msg
.split_once(" at line")
.map(|(v, _)| {
format!("{v} (Sorry for being unable to provide an exact location)")
})
.unwrap_or_else(|| "clients: invalid value".into())
} else {
err_msg
};
anyhow!("{err_msg}")
})
.with_context(err)?;
Ok(config)
}
fn load_dynamic(model_id: &str) -> Result<Self> {
let provider = match model_id.split_once(':') {
Some((v, _)) => v,
_ => model_id,
};
let is_openai_compatible = OPENAI_COMPATIBLE_PROVIDERS
.into_iter()
.any(|(name, _)| provider == name);
let client = if is_openai_compatible {
json!({ "type": "openai-compatible", "name": provider })
} else {
json!({ "type": provider })View on GitHub (pinned to 82976d349a)