{"record":{"id":"1f0602d83d0b3ce2","repo":"sipeed/picoclaw","slug":"fallback-model-q-has-no-active-provider","errorCode":null,"errorMessage":"fallback model %q has no active provider","messagePattern":"fallback model %q has no active provider","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/agent/pipeline_llm.go","lineNumber":711,"sourceCode":"\texec.activeModel = resolvedCandidateModel(candidates, rawModel)\n\texec.llmModel = exec.activeModel\n\texec.activeModelConfig = resolveActiveModelConfig(p.Cfg, ts.agent.Workspace, candidates, rawModel, defaultProvider)\n}\n\nfunc providerForFallbackCandidate(\n\tagent *AgentInstance,\n\tactiveProvider providers.LLMProvider,\n\tactiveCandidates []providers.FallbackCandidate,\n\tprovider string,\n\tmodel string,\n) (providers.LLMProvider, error) {\n\tif agent != nil {\n\t\tif cp, ok := agent.CandidateProviders[providers.ModelKey(provider, model)]; ok && cp != nil {\n\t\t\treturn cp, nil\n\t\t}\n\t}\n\tif activeProvider == nil {\n\t\treturn nil, fmt.Errorf(\"fallback model %q has no active provider\", model)\n\t}\n\treturn activeProvider, nil\n}\n\nfunc transientLLMRetryReason(err error) (string, bool) {\n\tif err == nil {\n\t\treturn \"\", false\n\t}\n\n\tif failErr := providers.ClassifyError(err, \"\", \"\"); failErr != nil {\n\t\tswitch failErr.Reason {\n\t\tcase providers.FailoverTimeout:\n\t\t\tif failErr.Status >= 500 {\n\t\t\t\treturn \"server_error\", true\n\t\t\t}\n\t\t\treturn \"timeout\", true\n\t\tcase providers.FailoverNetwork:\n\t\t\treturn \"network\", true","sourceCodeStart":693,"sourceCodeEnd":729,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/pkg/agent/pipeline_llm.go#L693-L729","documentation":"Returned by providerForFallbackCandidate when resolving a fallback candidate: the agent's CandidateProviders registry has no live provider under ModelKey(provider, model), and the active provider is nil, so there is no provider object to send the fallback request through. It means model fallback was configured but no usable provider client exists for it.","triggerScenarios":"A fallback model entry whose provider was never constructed — e.g. its API key/provider config missing so no candidate provider got registered in agent.CandidateProviders — combined with an activeProvider of nil (the primary provider itself failed to construct or was never set) at the moment a failover to that model is attempted.","commonSituations":"Fallback list referencing a provider whose credentials are absent in the environment; provider id typo in fallback config so the key never matches; disabling/removing a provider but leaving it in fallback lists; version changes to ModelKey/provider registration behavior.","solutions":["Add complete credentials/config for the fallback's provider so it gets registered in CandidateProviders","Correct the provider/model ids in the fallback configuration to match a configured provider exactly","Remove fallback entries whose providers are intentionally disabled","Ensure the primary provider is constructed before fallback resolution, so activeProvider is non-nil as a last resort"],"exampleFix":"# before\nproviders:\n  openai:\n    api_key: ${OPENAI_API_KEY}\nmodels:\n  fallbacks:\n    - provider: anthropic\n      model: claude-3-5-sonnet   # no anthropic credentials configured\n\n# after\nproviders:\n  openai:\n    api_key: ${OPENAI_API_KEY}\n  anthropic:\n    api_key: ${ANTHROPIC_API_KEY}\nmodels:\n  fallbacks:\n    - provider: anthropic\n      model: claude-3-5-sonnet","handlingStrategy":"validation","validationCode":"func validateFallbackProviders(cfg *config.Config, agent *AgentInstance) error {\n    for _, fb := range fallbacks(cfg) {\n        key := providers.ModelKey(fb.Provider, fb.Model)\n        if _, ok := agent.CandidateProviders[key]; !ok {\n            if !providerConfigured(cfg, fb.Provider) {\n                return fmt.Errorf(\"fallback %s/%s has no configured provider (missing credentials?)\", fb.Provider, fb.Model)\n            }\n        }\n    }\n    return nil\n}","typeGuard":"func isNoActiveProviderError(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"has no active provider\")\n}","tryCatchPattern":"prov, err := providerForFallbackCandidate(agent, active, candidates, provider, model)\nif err != nil {\n    if isNoActiveProviderError(err) {\n        // skip this fallback candidate rather than aborting the failover chain\n        log.Printf(\"skipping fallback %s/%s: %v\", provider, model, err)\n        continue\n    }\n    return nil, err\n}","preventionTips":["Register credentials for every provider referenced in fallback lists","Validate at startup that each fallback resolves to a live candidate provider","Skip unresolvable fallback candidates instead of failing the whole request"],"tags":["fallback","providers","config","llm","go"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}