{"record":{"id":"428182f6ca82e0d4","repo":"plandex-ai/plandex","slug":"model-config-is-nil","errorCode":null,"errorMessage":"model config is nil","messagePattern":"model config is nil","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/server/model/client.go","lineNumber":176,"sourceCode":"\t\t\tauthVars,\n\t\t\tsettings,\n\t\t\torgUserConfig,\n\t\t\tcurrentOrgId,\n\t\t\tcurrentUserId,\n\t\t)\n\n\t\tfallbackRes := modelConfig.GetFallbackForModelError(\n\t\t\tnumTotalRetry,\n\t\t\tdidProviderFallback,\n\t\t\tmodelErr,\n\t\t\tauthVars,\n\t\t\tsettings,\n\t\t\torgUserConfig,\n\t\t)\n\t\tresolvedModelConfig := fallbackRes.ModelRoleConfig\n\n\t\tif resolvedModelConfig == nil {\n\t\t\treturn nil, fallbackRes, fmt.Errorf(\"model config is nil\")\n\t\t}\n\n\t\tproviderComposite := resolvedModelConfig.GetProviderComposite(authVars, settings, orgUserConfig)\n\n\t\tbaseModelConfig := resolvedModelConfig.GetBaseModelConfig(authVars, settings, orgUserConfig)\n\n\t\topClient, ok := clients[providerComposite]\n\n\t\tif !ok {\n\t\t\treturn nil, fallbackRes, fmt.Errorf(\"client not found for provider composite: %s\", providerComposite)\n\t\t}\n\n\t\tif modelErr != nil && modelErr.Kind == shared.ErrCacheSupport {\n\t\t\tfor i := range req.Messages {\n\t\t\t\tfor j := range req.Messages[i].Content {\n\t\t\t\t\tif req.Messages[i].Content[j].CacheControl != nil {\n\t\t\t\t\t\treq.Messages[i].Content[j].CacheControl = nil\n\t\t\t\t\t}","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/model/client.go#L158-L194","documentation":"During streaming chat completion, the code resolves which model/fallback config to use via modelConfig.GetFallbackForModelError. If that returns a FallbackResult whose ModelRoleConfig is nil, there is no model role configuration to route the request to, and the library aborts with \"model config is nil\". This is an internal configuration-resolution failure: the fallback resolver produced no usable model config for this request/retry state.","triggerScenarios":"createChatCompletionStreamExtended is called through withStreamingRetries; on any retry (numTotalRetry > 0) or provider fallback (didProviderFallback) or model error, GetFallbackForModelError returns a FallbackResult whose ModelRoleConfig is nil — e.g. all configured fallback models exhausted, or the plan/org settings contain no config for the requested model role.","commonSituations":"Org/user plan settings reference a model role that is not configured; all fallback models have been tried and removed; misconfigured FallbackChains so the resolver runs out of candidates; settings deserialization yielding empty ModelRoleConfig entries.","solutions":["Verify PlanSettings/orgUserConfig define a valid ModelRoleConfig for every model role used by the request and its fallback chain.","Check GetFallbackForModelError: ensure the fallback chain for the requested model has at least one remaining candidate at every retry depth.","Log fallbackRes (number of retries, didProviderFallback, modelErr) before this error to see why resolution failed.","Guard the caller: validate modelConfig/fallback resolution before invoking the streaming call and surface a clear 'no model configured' error to the user."],"exampleFix":"// before\nfallbackRes := modelConfig.GetFallbackForModelError(...)\nresolvedModelConfig := fallbackRes.ModelRoleConfig\nif resolvedModelConfig == nil {\n    return nil, fallbackRes, fmt.Errorf(\"model config is nil\")\n}\n// after\nfallbackRes := modelConfig.GetFallbackForModelError(...)\nresolvedModelConfig := fallbackRes.ModelRoleConfig\nif resolvedModelConfig == nil {\n    return nil, fallbackRes, fmt.Errorf(\"model config is nil for model=%s after retries=%d fallback=%v: %w\",\n        req.Model, numTotalRetry, didProviderFallback, shared.ErrNoModelConfig)\n}","handlingStrategy":"validation","validationCode":"// before calling the streaming API\nif modelConfig == nil || modelConfig.GetFallbackForModelError(0, false, nil, authVars, settings, orgUserConfig).ModelRoleConfig == nil {\n    return fmt.Errorf(\"no model role configured for model %s; check plan settings and fallback chain\", req.Model)\n}","typeGuard":"func hasModelConfig(fb shared.FallbackResult) bool {\n    return fb.ModelRoleConfig != nil\n}","tryCatchPattern":"resp, fallbackRes, err := createChatCompletionStreamExtended(...)\nif err != nil {\n    if strings.Contains(err.Error(), \"model config is nil\") {\n        log.Printf(\"model routing failed: retries/fallbacks exhausted, fallbackRes=%+v\", fallbackRes)\n        return fmt.Errorf(\"no model available for this request: %w\", err)\n    }\n    return err\n}","preventionTips":["Keep every model role in PlanSettings backed by a valid ModelRoleConfig.","Make fallback chains terminate in a always-available default model.","Add a startup test that resolves all model roles with empty/edge-case settings.","Fail fast at settings load time when a role resolves to nil."],"tags":["go","configuration","model-routing"],"backgroundTag":"missing-model-configuration","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}