zeroclaw-labs/zeroclaw · warning · DiagItem
{} (at {})
Error message
{} (at {}) What it means
Not a single check but the aggregation point: `check_config_semantics` forwards every warning from `Config::collect_warnings()` — the single source of truth shared with the gateway API and `Config::validate()` tracing — formatting each as `<message> (at <config path>)`. Typical warnings behind this wrapper are dangling model fallback references and `wire_api` misuse. Doctor deliberately does not duplicate those checks; it only re-reports them with their config path.
Source
Thrown at crates/zeroclaw-runtime/src/doctor/mod.rs:1381
let provider_ref = agent.model_provider.as_str();
if provider_ref.is_empty() {
continue;
}
if let Some(reason) = provider_validation_error(config, provider_ref) {
items.push(DiagItem::warn(
cat,
format!(
"agent \"{name}\" uses invalid model_provider \"{provider_ref}\": {reason}",
),
));
}
}
// Non-fatal config warnings — dangling fallback refs, wire_api misuse, etc.
// Source of truth: `Config::collect_warnings()` (same signal as gateway API
// and `Config::validate()` tracing). Do not duplicate checks here.
for warning in config.collect_warnings() {
items.push(DiagItem::warn(
cat,
format!("{} (at {})", warning.message, warning.path),
));
}
}
fn check_web_dist_dir(config: &Config, items: &mut Vec<DiagItem>) {
let cat = "config";
match config.gateway.web_dist_dir.as_deref() {
None => {}
Some(value) => match web_dist_dir_expansion_reason_key(value) {
None => {}
Some(reason_key) => {
let reason = crate::i18n::get_required_cli_string(reason_key);
let message = crate::i18n::get_required_cli_string_with_args(
"cli-doctor-web-dist-dir-expansion-warning",
&[("path", value), ("reason", reason.as_str())],
);View on GitHub (pinned to 88bb9c8533)
Solutions
- Read the message together with the `(at <path>)` suffix — the path names the exact config key to fix.
- Fix the referenced key (restore the missing provider, correct the dangling fallback, set a valid `wire_api`).
- Re-run `zeroclaw doctor`; the same warning source feeds `Config::validate()` tracing and the gateway API, so a clean doctor means those surfaces are clean too.
Defensive patterns
Strategy: validation
Validate before calling
for warning in config.collect_warnings() {
eprintln!("config warning at {}: {}", warning.path, warning.message);
} Prevention
- Treat `collect_warnings()` output as a build failure in CI, not log noise.
- After renaming/removing providers, grep config for the old names before deploying.
When it happens
Trigger: Running `zeroclaw doctor`/`diagnose` on any config where `collect_warnings()` yields at least one entry, e.g. a `fallback` naming a provider that does not exist, or a `wire_api` value that does not fit the configured provider type.
Common situations: Renaming or deleting a provider while a fallback still points at the old name; switching a provider between chat/completions styles without updating `wire_api`; hand-editing config keys doctor's own checks do not cover.
Related errors
- model route "{}" uses invalid model_provider "{}": {}
- embedding route "{}" uses invalid model_provider "{}": {}
- agent "{name}" uses invalid model_provider "{provider_ref}":
- config section `{$path}` is malformed and was reset to defau
- {label}: no api_key set (may rely on env vars or model_provi
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/d02fdd87d777ee3f.
Report an issue: GitHub.