{"record":{"id":"58f1fee5e79fdfc6","repo":"microsoft/autogen","slug":"finishreason-finishreason-is-not-supported","errorCode":null,"errorMessage":"FinishReason {finishReason} is not supported","messagePattern":"FinishReason (.+?) is not supported","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"dotnet/src/AutoGen.Mistral/Middleware/MistralChatMessageConnector.cs","lineNumber":166,"sourceCode":"            throw new NotSupportedException(\"response.Choices.Count != 1\");\n        }\n\n        var choice = response.Choices[0];\n        var finishReason = choice.FinishReason ?? throw new ArgumentNullException(\"choice.FinishReason\");\n\n        if (finishReason == Choice.FinishReasonEnum.Stop || finishReason == Choice.FinishReasonEnum.Length)\n        {\n            return new TextMessage(Role.Assistant, choice.Message?.Content ?? throw new ArgumentNullException(\"choice.Message.Content\"), from: from.Name);\n        }\n        else if (finishReason == Choice.FinishReasonEnum.ToolCalls)\n        {\n            var functionContents = choice.Message?.ToolCalls ?? throw new ArgumentNullException(\"choice.Message.ToolCalls\");\n            var toolCalls = functionContents.Select(f => new ToolCall(f.Function.Name, f.Function.Arguments) { ToolCallId = f.Id }).ToList();\n            return new ToolCallMessage(toolCalls, from: from.Name);\n        }\n        else\n        {\n            throw new NotSupportedException($\"FinishReason {finishReason} is not supported\");\n        }\n    }\n\n    private IMessage? ProcessChatCompletionResponse(IMessage<ChatCompletionResponse> message, IAgent agent)\n    {\n        var response = message.Content;\n        if (response.VarObject != \"chat.completion.chunk\")\n        {\n            throw new NotSupportedException($\"VarObject {response.VarObject} is not supported\");\n        }\n        if (response.Choices is null)\n        {\n            throw new ArgumentNullException(\"response.Choices\");\n        }\n\n        if (response.Choices?.Count != 1)\n        {\n            throw new NotSupportedException(\"response.Choices.Count != 1\");","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/dotnet/src/AutoGen.Mistral/Middleware/MistralChatMessageConnector.cs#L148-L184","documentation":"NotSupportedException indicating the Mistral response's finish_reason is none of stop, length, or tool_calls. The connector only maps these three terminal reasons; anything else (e.g. 'model_length', 'function_call' from legacy APIs, or a new Mistral finish reason) is rejected.","triggerScenarios":"Non-streaming Mistral completion whose finish_reason is a value outside {stop, length, tool_calls}. Examples: legacy 'function_call' responses from function-calling APIs, new finish reasons Mistral introduces (e.g. content-filter related), or enum parsing that yields an unexpected value.","commonSituations":"Mistral introducing a new finish_reason after the SDK was vendored; using a Mistral-compatible endpoint (OpenAI-style proxies) that emit 'function_call'; explicitly requesting legacy function calling instead of tool calling.","solutions":["Capture the raw finish_reason string from the API response to identify the exact value.","If it is a legitimate new reason, extend the if/else chain in the connector to handle it (or map unknown reasons to a text message with diagnostics).","Switch from legacy function_call parameters to the current tool-calling API if using an OpenAI-compatible shim.","Upgrade AutoGen.Mistral; newer releases may support additional finish reasons."],"exampleFix":"// before\nelse\n{\n    throw new NotSupportedException($\"FinishReason {finishReason} is not supported\");\n}\n\n// after\nelse\n{\n    // degrade gracefully: surface whatever content exists instead of crashing\n    return new TextMessage(Role.Assistant, choice.Message?.Content ?? string.Empty, from: from.Name);\n}","handlingStrategy":"fallback","validationCode":"var supported = new[] { Choice.FinishReasonEnum.Stop, Choice.FinishReasonEnum.Length, Choice.FinishReasonEnum.ToolCalls };\nif (!supported.Contains(choice.FinishReason!.Value))\n{\n    // map unknown finish reasons to a safe text message before the connector throws\n    return new TextMessage(Role.Assistant, choice.Message?.Content ?? \"[unsupported finish reason]\", from: agent.Name);\n}","typeGuard":"static bool IsSupportedFinishReason(Choice.FinishReasonEnum? r) => r is Choice.FinishReasonEnum.Stop or Choice.FinishReasonEnum.Length or Choice.FinishReasonEnum.ToolCalls;","tryCatchPattern":"catch (NotSupportedException ex) when (ex.Message.Contains(\"FinishReason\"))\n{\n    logger.LogWarning(\"Unhandled Mistral finish reason: {Message}\", ex.Message);\n    // degrade to retry or end the turn instead of crashing the orchestration\n}","preventionTips":["Subscribe to Mistral API changelogs for new finish_reason values","Wrap agent turns in an orchestrator-level catch for NotSupportedException"],"tags":["mistral","finish-reason","not-supported","api-drift"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}