{"record":{"id":"6d7340b02c0ef396","repo":"LykosAI/StabilityMatrix","slug":"provider-providerid-not-found","errorCode":null,"errorMessage":"Provider {providerId} not found","messagePattern":"Provider (.+?) not found","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"StabilityMatrix.Core/Services/ImageGeneration/ImageGenerationChatService.cs","lineNumber":431,"sourceCode":"        Guid conversationId,\n        string providerId,\n        string? textPrompt,\n        List<string>? imagePaths,\n        Dictionary<string, object>? providerOptions,\n        IProgress<ImageGenerationProgress>? progress,\n        CancellationToken cancellationToken = default\n    )\n    {\n        var conversation = await GetConversationAsync(conversationId).ConfigureAwait(false);\n        if (conversation == null)\n        {\n            throw new InvalidOperationException($\"Conversation {conversationId} not found\");\n        }\n\n        var provider = GetProvider(providerId);\n        if (provider == null)\n        {\n            throw new InvalidOperationException($\"Provider {providerId} not found\");\n        }\n\n        // Update conversation's provider if it changed\n        var providerChanged = conversation.ProviderId != providerId;\n        if (providerChanged)\n        {\n            logger.LogInformation(\n                \"Switching conversation {ConversationId} provider from {OldProvider} to {NewProvider}\",\n                conversationId,\n                conversation.ProviderId,\n                providerId\n            );\n            conversation.ProviderId = providerId;\n        }\n\n        // Check for provider compatibility - thought signature requirements\n        // If switching to a thinking model with incompatible history, we'll carry forward\n        // the last output image as an input instead of using the full history","sourceCodeStart":413,"sourceCodeEnd":449,"githubUrl":"https://github.com/LykosAI/StabilityMatrix/blob/af93d6ef57c01cd890d7e0ad0a9ea8c9fcda3002/StabilityMatrix.Core/Services/ImageGeneration/ImageGenerationChatService.cs#L413-L449","documentation":"After confirming the conversation exists, SendMessageAsync resolves the image-generation provider by its string id via GetProvider. If no registered provider matches providerId, an InvalidOperationException is thrown. Providers are the registered backends (e.g. cloud API providers); the id must match one the service knows about.","triggerScenarios":"Calling SendMessageAsync with a providerId string that does not match any registered provider — misspelled id, provider from a different app version, provider removed/unregistered at startup, or an id read from a conversation record saved by an older build.","commonSituations":"Config or persisted settings referencing a provider that was renamed between versions; passing a raw provider name string instead of the canonical ProviderId; provider registration failed silently at startup; tests using made-up provider ids.","solutions":["Print/list the available providers and use an exact registered ProviderId (check GetProviders/provider registration in the service).","Update stale provider ids in settings/conversation records after upgrading the app.","Ensure provider registration (DI/startup) succeeded — a failed registration makes all ids unresolvable.","Guard with a lookup: resolve the provider id against the available provider list before calling SendMessageAsync."],"exampleFix":"// before\nawait chatService.SendMessageAsync(convId, \"gemini-pro\", prompt); // wrong id\n// after\nvar providers = chatService.GetProviders();\nvar providerId = providers.FirstOrDefault(p => p.Id.Contains(\"gemini\"))?.Id\n    ?? throw new InvalidOperationException(\"No gemini provider registered\");\nawait chatService.SendMessageAsync(convId, providerId, prompt);","handlingStrategy":"validation","validationCode":"var knownProviders = chatService.GetProviders(); // or the registration list\nstring providerId = /* configured id */;\nif (!knownProviders.Any(p => string.Equals(p.Id, providerId, StringComparison.OrdinalIgnoreCase)))\n{\n    throw new InvalidOperationException($\"Unknown provider '{providerId}'. Available: {string.Join(\", \", knownProviders.Select(p => p.Id))}\");\n}","typeGuard":"bool IsRegisteredProvider(string id, IEnumerable<ImageGenerationProvider> providers) =>\n    providers.Any(p => string.Equals(p.Id, id, StringComparison.OrdinalIgnoreCase));","tryCatchPattern":"try\n{\n    await chatService.SendMessageAsync(conversationId, providerId, prompt);\n}\ncatch (InvalidOperationException ex) when (ex.Message.StartsWith(\"Provider \"))\n{\n    logger.LogError(ex, \"Provider '{ProviderId}' not registered\", providerId);\n    providerId = chatService.GetProviders().First().Id; // fall back to first registered provider\n    await chatService.SendMessageAsync(conversationId, providerId, prompt);\n}","preventionTips":["Resolve provider ids from GetProviders() rather than hardcoded strings","Migrate persisted provider ids after app upgrades (renames/removals)","Verify provider DI registration succeeds at startup and log the registered set","Normalize casing when comparing provider ids"],"tags":["configuration","invalid-argument","provider","lookup"],"backgroundTag":"record-not-found","analyzedSha":"af93d6ef57c01cd890d7e0ad0a9ea8c9fcda3002","analyzedAt":"2026-09-12T19:02:43.389Z","contentChangedAt":"2026-09-12T19:02:43.389Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}