{"record":{"id":"cb9deaada009953d","repo":"LykosAI/StabilityMatrix","slug":"no-user-message-found-to-retry","errorCode":null,"errorMessage":"No user message found to retry","messagePattern":"No user message found to retry","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"StabilityMatrix.Core/Services/ImageGeneration/ImageGenerationChatService.cs","lineNumber":856,"sourceCode":"                    carryForwardImagePath = GetMessageImagePaths(lastAssistantImage)\n                        .FirstOrDefault(File.Exists);\n                    if (carryForwardImagePath != null)\n                    {\n                        logger.LogInformation(\n                            \"Retry: Switching to thinking model with incompatible history. \"\n                                + \"Carrying forward last image as input: {ImagePath}\",\n                            carryForwardImagePath\n                        );\n                    }\n                }\n            }\n        }\n\n        // Find the last user message\n        var lastUserMessage = allMessages.LastOrDefault(m => m.Role == MessageRole.User);\n        if (lastUserMessage == null)\n        {\n            throw new InvalidOperationException(\"No user message found to retry\");\n        }\n\n        // Build conversation history (everything except the last user message)\n        // If we're carrying forward an image, skip the incompatible history\n        var conversationHistory = new List<ConversationMessage>();\n\n        if (string.IsNullOrEmpty(carryForwardImagePath))\n        {\n            foreach (var m in allMessages.Where(msg => msg.Id != lastUserMessage.Id))\n            {\n                var messageImagePaths = GetMessageImagePaths(m).Where(File.Exists).ToList();\n\n                if (messageImagePaths.Count == 0)\n                {\n                    conversationHistory.Add(\n                        new ConversationMessage\n                        {\n                            Role = m.Role,","sourceCodeStart":838,"sourceCodeEnd":874,"githubUrl":"https://github.com/LykosAI/StabilityMatrix/blob/af93d6ef57c01cd890d7e0ad0a9ea8c9fcda3002/StabilityMatrix.Core/Services/ImageGeneration/ImageGenerationChatService.cs#L838-L874","documentation":"RetryGenerationAsync loads all conversation messages and looks for the last message with Role == MessageRole.User, since a retry needs the original prompt to re-send. If the conversation contains no user message (empty conversation, or only assistant/system messages), it throws InvalidOperationException. This prevents retrying a conversation that has nothing to retry.","triggerScenarios":"Calling RetryGenerationAsync on a conversation whose message list contains zero messages with Role User - e.g. a freshly created empty conversation, a conversation where generation failed before the user message was persisted, or a conversation containing only assistant/system messages.","commonSituations":"Retrying immediately after a failed first generation that never saved the user message; retrying a newly created conversation by mistake; test/debug conversations constructed programmatically without user turns.","solutions":["Check that the conversation has at least one user message before calling RetryGenerationAsync","If the conversation is empty, send a new prompt via the normal generate path instead of retry","Inspect persisted messages (GetMessagesAsync) and repair/re-seed the user message if it was lost","Verify the retry targets the correct conversationId"],"exampleFix":"// before\nawait chatService.RetryGenerationAsync(conversationId, providerId);\n// after\nvar messages = await chatService.GetMessagesAsync(conversationId);\nif (!messages.Any(m => m.Role == MessageRole.User))\n{\n    throw new InvalidOperationException(\"Nothing to retry: no user message in this conversation.\");\n}\nawait chatService.RetryGenerationAsync(conversationId, providerId);","handlingStrategy":"validation","validationCode":"var hasUserMessage = (await chatService.GetMessagesAsync(conversationId))\n    .Any(m => m.Role == MessageRole.User);\nif (!hasUserMessage) return; // nothing to retry","typeGuard":"bool IsRetryable(IReadOnlyList<ConversationMessage> msgs) =>\n    msgs.Any(m => m.Role == MessageRole.User);","tryCatchPattern":"try { await chatService.RetryGenerationAsync(convId, providerId); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"No user message\"))\n{\n    // disable retry UI / start a new prompt instead\n}","preventionTips":["Only enable retry when the conversation shows a user message","Check message persistence succeeded after the first generation","Guard against retrying freshly created empty conversations"],"tags":["empty-conversation","invalid-state","retry"],"backgroundTag":"empty-result-set","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"}