{"record":{"id":"0fd021452eecd629","repo":"zeroclaw-labs/zeroclaw","slug":"agents-agent-alias-model-provider-agent-ref","errorCode":null,"errorMessage":"agents.{agent_alias}.model_provider = \"{agent_ref}\" does not resolve to a configured [providers.models.<type>.<alias>] entry","messagePattern":"agents\\.(.+?)\\.model_provider = \"(.+?)\" does not resolve to a configured \\[providers\\.models\\.<type>\\.<alias>\\] entry","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-runtime/src/agent/agent.rs","lineNumber":1566,"sourceCode":"            // None for the runtime profile and silently falls back to the\n            // schema default of 20 actions/hour regardless of config.\n            let mut policy = SecurityPolicy::for_agent(config, agent_alias).with_context(|| {\n                format!(\"agents.{agent_alias}: failed to build security policy\")\n            })?;\n            if let Some(cwd) = session_cwd {\n                policy.workspace_dir = cwd.to_path_buf();\n                policy.allowed_roots.push(agent_workspace.clone());\n            }\n            policy\n        });\n\n        let (provider_name, provider_alias, agent_model_provider) =\n            match config.resolved_model_provider_for_agent(agent_alias) {\n                Some(resolved) => (resolved.0, resolved.1, Some(resolved.2)),\n                None => {\n                    let agent_ref = agent_cfg.model_provider.as_str();\n                    if !agent_ref.is_empty() {\n                        anyhow::bail!(\n                            \"agents.{agent_alias}.model_provider = \\\"{agent_ref}\\\" does not \\\n                             resolve to a configured [providers.models.<type>.<alias>] entry\"\n                        );\n                    }\n                    // V3 schema requires every agent to set model_provider.\n                    // Empty is a config error rather than a silent fallback.\n                    anyhow::bail!(\n                        \"agents.{agent_alias}.model_provider is empty — set it to a \\\n                         configured \\\"<type>.<alias>\\\" (e.g. \\\"anthropic.{agent_alias}\\\")\"\n                    );\n                }\n            };\n        let memory: Arc<dyn Memory> = zeroclaw_memory::create_memory_for_agent(\n            config,\n            agent_alias,\n            agent_model_provider.and_then(|e| e.api_key.as_deref()),\n        )\n        .await?;","sourceCodeStart":1548,"sourceCodeEnd":1584,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-runtime/src/agent/agent.rs#L1548-L1584","documentation":"Under the V3 config schema every agent's model_provider must be a \"<type>.<alias>\" reference that resolves to an existing [providers.models.<type>.<alias>] table. During agent construction (resolved_model_provider_for_agent returning None with a non-empty ref), ZeroClaw bails rather than guessing a provider — a dangling reference is treated as a hard config error, not a silent fallback.","triggerScenarios":"model_provider = \"anthropic.main\" while the table is [providers.models.anthropic.default]; typo in either the type or alias segment; the [providers.models.*] table missing entirely; V2-era configs referencing a bare provider name.","commonSituations":"Renaming a provider alias without updating agents that point at it; migrating from an older schema where agents referenced providers differently; config split across files and the models table never gets included.","solutions":["Compare the reference string character-by-character with the table header [providers.models.<type>.<alias>].","Add the missing [providers.models.<type>.<alias>] table with at least a model key.","Run ZeroClaw's config validation/doctor command to catch every dangling agent ref at once.","If you renamed an alias, update every agents.<alias>.model_provider that referenced the old name."],"exampleFix":"# before — reference does not match the table name\n[providers.models.anthropic.default]\nmodel = \"claude-sonnet-4-5\"\n\n[agents.helper]\nmodel_provider = \"anthropic.main\"\n\n# after\n[agents.helper]\nmodel_provider = \"anthropic.default\"","handlingStrategy":"validation","validationCode":"// Startup lint: every agent ref must resolve\nfor (alias, agent) in &config.agents {\n    let r = agent.model_provider.as_str();\n    anyhow::ensure!(\n        !r.is_empty() && config.resolved_model_provider_for_agent(alias).is_some(),\n        \"agents.{alias}.model_provider '{r}' does not resolve\"\n    );\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run zeroclaw's config validation/doctor after every alias rename","Define provider tables before agents that reference them in reviewed config PRs","Treat agent construction failure as a deploy-time signal — fail the deploy, do not boot partially"],"tags":["config","agents","model-provider","validation","v3-schema"],"backgroundTag":"unresolved-config-reference","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}