{"record":{"id":"ceae8b99c143385f","repo":"Hmbown/CodeWhale","slug":"fleet-task-reason-source-source","errorCode":null,"errorMessage":"Fleet task `{}`: {reason} (source={source})","messagePattern":"Fleet task `(.+?)`: (.+?) \\(source=(.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/fleet/worker_runtime.rs","lineNumber":92,"sourceCode":"        let agent_profile = resolve_task_agent_profile(task, agent_profiles)\n            .ok()\n            .flatten();\n        let (model, source) =\n            effective_fleet_model_with_source(run_model, task.worker.as_ref(), agent_profile);\n        let pinned_model = matches!(source, \"task.model\" | \"agent_profile.model\");\n        let explicit_provider = explicit_fleet_provider_id(agent_profile);\n        if pinned_model && explicit_provider.is_none() {\n            let (provider, base_url) = config.map_or_else(\n                || {\n                    let provider = ApiProvider::Deepseek;\n                    (provider, provider.default_base_url().to_string())\n                },\n                |config| (config.api_provider(), config.deepseek_base_url()),\n            );\n            if let Err(reason) =\n                crate::route_runtime::validate_unpinned_model_provider(provider, &model, &base_url)\n            {\n                bail!(\"Fleet task `{}`: {reason} (source={source})\", task.id);\n            }\n        }\n\n        let route = resolve_fleet_route_with_config(task, agent_profiles, session_model, config);\n        if route.is_some() {\n            validate_fleet_reasoning_effort(task, agent_profiles, session_model, config)?;\n        }\n        if !pinned_model {\n            continue;\n        }\n        // A concrete model is pinned at the task/profile level; it must resolve\n        // to a real provider route or the worker cannot launch.\n        if route.is_some() {\n            continue;\n        }\n        let provider = explicit_provider\n            .map(|provider| format!(\"provider=`{provider}`\"))\n            .unwrap_or_else(|| {","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/fleet/worker_runtime.rs#L74-L110","documentation":"A fleet task pins a concrete model but declares no explicit provider, so the runtime must validate that model against the session/default provider (falling back to DeepSeek with its default base URL when no config exists). `validate_unpinned_model_provider` rejected the combination, and this bail wraps its reason with the task id and the `source` that pinned the model. In short: the provider that would have to serve this model cannot.","triggerScenarios":"A task whose worker profile pins `model = \"claude-...\"` (or any model not served by the active provider) with no `agent_profile` that sets an explicit provider; running on a machine whose session provider is DeepSeek or whose config points at a base_url/gateway that does not expose that model id.","commonSituations":"Copying a fleet spec from a teammate with a different default provider; removing or renaming a provider config so the fallback Deepseek route no longer matches; pointing deepseek_base_url at a proxy whose model catalog differs from the official API.","solutions":["Set an explicit provider for that model in the agent profile the task references, so validation no longer runs against the session/default provider.","Switch the task's model role to `inherit` so it uses the session model instead of a pin.","Fix the model id or the provider config (base_url, credentials) so the session/default provider actually serves the pinned model.","Read the embedded `{reason}` and `{source}`: the reason says what the provider check rejected, the source says whether the pin came from the task or the profile."],"exampleFix":"# before (agent profile TOML)\nid = \"implementer\"\nmodel = \"claude-sonnet-4\"\n# no provider declared\n\n# after\nid = \"implementer\"\nprovider = \"anthropic\"\nmodel = \"claude-sonnet-4\"","handlingStrategy":"validation","validationCode":"// Before launching the fleet, ensure every pinned model is servable by the\n// provider that will resolve it: either the profile sets an explicit provider,\n// or the model must exist on the session/default provider.\nfn profile_pins_are_servable(tasks: &[FleetTaskSpec], profiles: &[AgentProfile], session_model: &str) -> bool {\n    tasks.iter().all(|t| {\n        let pinned = effective_model(t, profiles);\n        pinned.is_none() || pinned.as_deref() == Some(session_model) || has_explicit_provider(t, profiles)\n    })\n}","typeGuard":null,"tryCatchPattern":"match run_fleet_launch(&spec) {\n    Err(e) if e.to_string().contains(\"Fleet task `\") && e.to_string().contains(\"source=\") => {\n        // provider/model mismatch: read {reason} and {source}, fix profile or switch role to inherit\n        report_route_misconfiguration(e);\n    }\n    other => other,\n}","preventionTips":["Always pair a pinned model with an explicit provider in the agent profile.","Prefer role = \"inherit\" unless a task truly needs a specific model.","After changing provider config or base_url, dry-run one fleet task before a full run."],"tags":["fleet","model-routing","provider","validation","rust"],"backgroundTag":"model-provider-mismatch","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}