{"record":{"id":"1c8e705c97b94421","repo":"zeroclaw-labs/zeroclaw","slug":"agents-agent-alias-model-provider-agent-ref-1c8e70","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/loop_.rs","lineNumber":2908,"sourceCode":"        // Profile values (when set) override the agent's inline fields.\n        // See `Config::resolved_agent_config` for precedence rules.\n        let eff_compact_context = agent.resolved.compact_context;\n        let eff_max_system_prompt_chars = agent.resolved.max_system_prompt_chars;\n        let eff_prompt_injection_mode = agent.resolved.prompt_injection_mode;\n\n        let observer: Arc<dyn Observer> =\n            Arc::from(observability::create_observer(&config.observability));\n        let runtime: Arc<dyn platform::RuntimeAdapter> =\n            Arc::from(platform::create_runtime(&config.runtime)?);\n        let security = Arc::new(SecurityPolicy::for_agent(&config, agent_alias)?);\n        let (provider_name, provider_alias, agent_model_provider) = match config\n            .resolved_model_provider_for_agent(agent_alias)\n        {\n            Some(resolved) => (resolved.0, resolved.1.to_string(), Some(resolved.2.clone())),\n            None => {\n                let agent_ref = agent.model_provider.as_str();\n                if !agent_ref.is_empty() {\n                    anyhow::bail!(\n                        \"agents.{agent_alias}.model_provider = \\\"{agent_ref}\\\" does not resolve to \\\n                     a configured [providers.models.<type>.<alias>] entry\"\n                    );\n                }\n                anyhow::bail!(\n                    \"agents.{agent_alias}.model_provider is empty \\u{2014} set it to a configured \\\n                 \\\"<type>.<alias>\\\" (e.g. \\\"anthropic.{agent_alias}\\\")\"\n                );\n            }\n        };\n        let approval_manager = ApprovalManager::for_non_interactive(&risk_profile);\n        let mem: Arc<dyn Memory> = zeroclaw_memory::create_memory_for_agent(\n            &config,\n            agent_alias,\n            agent_model_provider\n                .as_ref()\n                .and_then(|e| e.api_key.as_deref()),\n        )","sourceCodeStart":2890,"sourceCodeEnd":2926,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-runtime/src/agent/loop_.rs#L2890-L2926","documentation":"The same dangling-reference guard as at construction time, enforced again on the non-interactive process_message path (cron, channels, gateway-driven turns): agents.<alias>.model_provider is non-empty but resolved_model_provider_for_agent returns None, so no [providers.models.<type>.<alias>] table matches it. Re-checking at message time catches configs edited after agent construction.","triggerScenarios":"A gateway/cron/channel turn referencing an agent whose provider table was renamed or deleted after startup; two config layers where the models table is missing in the layer the runtime actually loaded.","commonSituations":"Editing config while a daemon is running so agents and provider tables drift out of sync; deploying a partial config; renaming aliases in one file but not the agents file.","solutions":["Fix the reference to match an existing [providers.models.<type>.<alias>] table (check exact spelling of both segments).","Restore or add the missing provider table.","Reload/restart the runtime after config edits so agents and providers load from one snapshot.","Run the config validation command after every rename."],"exampleFix":"# before\n[agents.scheduler]\nmodel_provider = \"openai.codex\"   # table is [providers.models.openai.main]\n\n# after\n[agents.scheduler]\nmodel_provider = \"openai.main\"","handlingStrategy":"validation","validationCode":"// Re-validate before dispatching non-interactive turns\nfor alias in scheduled_agents {\n    anyhow::ensure!(\n        config.resolved_model_provider_for_agent(alias).is_some(),\n        \"agent {alias} has a dangling model_provider — reload config\"\n    );\n}","typeGuard":null,"tryCatchPattern":"Catch the error per-message in channel/cron dispatch so one misconfigured agent does not kill the daemon; log agent + reference, skip the turn, and alert — the config must be fixed and reloaded.","preventionTips":["Reload/restart the runtime atomically after config edits so agents and provider tables stay in sync","Never rename a provider alias without grep-updating all model_provider refs","Validate the combined config layers actually loaded, not just the file you edited"],"tags":["config","agents","model-provider","validation","gateway"],"backgroundTag":"unresolved-config-reference","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}