{"record":{"id":"02ae9049ededae16","repo":"sipeed/picoclaw","slug":"model-q-did-not-resolve-to-any-provider-candidate","errorCode":null,"errorMessage":"model %q did not resolve to any provider candidates","messagePattern":"model %q did not resolve to any provider candidates","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/agent/agent_command.go","lineNumber":313,"sourceCode":"\t\t}\n\t\trt.GetModelInfo = func() (string, string) {\n\t\t\treturn agent.Model, resolvedCandidateProvider(agent.Candidates, cfg.Agents.Defaults.Provider)\n\t\t}\n\t\trt.SwitchModel = func(value string) (string, error) {\n\t\t\tvalue = strings.TrimSpace(value)\n\t\t\tmodelCfg, err := resolvedModelConfig(cfg, value, agent.Workspace)\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", err\n\t\t\t}\n\n\t\t\tnextProvider, _, err := providers.CreateProviderFromConfig(modelCfg)\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", fmt.Errorf(\"failed to initialize model %q: %w\", value, err)\n\t\t\t}\n\n\t\t\tnextCandidates := resolveModelCandidates(cfg, cfg.Agents.Defaults.Provider, value, agent.Fallbacks)\n\t\t\tif len(nextCandidates) == 0 {\n\t\t\t\treturn \"\", fmt.Errorf(\"model %q did not resolve to any provider candidates\", value)\n\t\t\t}\n\n\t\t\toldModel := agent.Model\n\t\t\toldProvider := agent.Provider\n\t\t\tagent.Model = value\n\t\t\tagent.Provider = nextProvider\n\t\t\tagent.Candidates = nextCandidates\n\t\t\tagent.ThinkingLevel = parseThinkingLevel(modelCfg.ThinkingLevel)\n\t\t\tagent.ThinkingLevelConfigured = isConfiguredThinkingLevel(modelCfg.ThinkingLevel)\n\n\t\t\tif oldProvider != nil && oldProvider != nextProvider {\n\t\t\t\tif stateful, ok := oldProvider.(providers.StatefulProvider); ok {\n\t\t\t\t\tstateful.Close()\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn oldModel, nil\n\t\t}\n","sourceCodeStart":295,"sourceCodeEnd":331,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/pkg/agent/agent_command.go#L295-L331","documentation":"After successfully constructing a provider for the requested model, SwitchModel calls resolveModelCandidates(cfg, defaultProvider, value, agent.Fallbacks) to build the fallback candidate chain and gets an empty list. Without candidates the agent has no usable model chain to run on, so the switch is aborted before any agent state (Model/Provider/Candidates) mutates.","triggerScenarios":"Config defines the model name but no provider mapping resolves it (e.g. provider defaults disagree with the model entry); fallback chain misconfigured such that filtering removes every candidate; referencing a model alias that exists for provider creation but not in the candidate-resolution rules.","commonSituations":"Hand-edited config where agents.defaults.provider points at a provider that does not offer the requested model; upgrade changed candidate resolution semantics; duplicate model names across providers with ambiguous resolution; empty fallbacks list plus mismatched default provider.","solutions":["Check agents.defaults.provider in config matches a provider that serves the requested model","Re-run /model with the fully qualified model identifier used elsewhere in config","Print/inspect resolvedModelConfig and resolveModelCandidates inputs (config excerpts) to see why the chain is empty","Fall back to a known-good model name, then re-add the problematic one step by step"],"exampleFix":"# before\nagents:\n  defaults:\n    provider: anthropic\nmodels:\n  fast:\n    provider: openai   # never reachable as a candidate\n\n# after\nagents:\n  defaults:\n    provider: openai","handlingStrategy":"validation","validationCode":"candidates := resolveModelCandidates(cfg, cfg.Agents.Defaults.Provider, value, agent.Fallbacks)\nif len(candidates) == 0 {\n    // chain empty: fix agents.defaults.provider vs model entry before calling SwitchModel\n}","typeGuard":"func modelHasCandidates(cfg *config.Config, provider, value string, fallbacks []string) bool {\n    return len(resolveModelCandidates(cfg, provider, value, fallbacks)) > 0\n}","tryCatchPattern":null,"preventionTips":["Keep agents.defaults.provider aligned with the providers of switchable models","Lint config: every switchable model must yield >=1 candidate under the default provider","Prefer fully-qualified model identifiers over aliases"],"tags":["model","configuration","fallback-chain"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}