Eine Cloud Computing-Plattform und -Infrastruktur für die Erstellung, Bereitstellung und Verwaltung von Anwendungen und Diensten über ein weltweites Netzwerk aus Rechenzentren, die von Microsoft verwaltetet werden.
Azure OpenAI: Wrong API status code formatting
The Azure OpenAI Service returns a validation error for certain inputs for the ChatCompleteAsync Api, the response looks similar to:
{
"requestid": "1b7cfa98-de62-440f-b230-72919bfa42a0",
"code": 400,
"message": "Validation error at #/max_completion_tokens: Extra inputs are not permitted"
}
The .NET SDK expects the "code" property to be a string and the parsing throws an exception
System.InvalidOperationException
HResult=0x80131509
Message=The requested operation requires an element of type 'String', but the target element has type 'Number'.
Source=System.Text.Json
StackTrace:
at System.Text.Json.ThrowHelper.ThrowJsonElementWrongTypeException(JsonTokenType expectedType, JsonTokenType actualType) in System.Text.Json\ThrowHelper.cs:line 288
The unfortunate side effect of this exception is, that this exception is caught and a generic BadRequestException is thrown, which does not contain the details anymore. You have to enable break on all exception in Visual Studio to actually see the relevant exception.
I opened an issue on the OpenAI SDK github for it but the OpenAI team responded, that the parser is correct and the schema requires the "code" property to be a string and that I should open an issue here as this needs to be fixed on Azure's side.
See: https://github.com/openai/openai-dotnet/issues/669 for the full history
A full repro of the probem:
// use with reasoning model, e.g. gpt-5-mini, enable Break on all Exceptions
using System.ClientModel;
using System.ClientModel.Primitives;
using System.Text.Json;
using Azure.AI.OpenAI;
using Azure.AI.OpenAI.Chat;
using OpenAI;
using OpenAI.Assistants;
using OpenAI.Chat;
namespace ConsoleApp3
{
internal class Program
{
static async Task Main(string[] args)
{
const string openAiEndpoint = "https://your_ai_endpoint.openai.azure.com/";
const string openAiKey = "Key";
const string searchEndpoint = "https://does_not_matter.search.windows.net";
const string indexName = "vector";
const string searchKey = "Key";
const string semanticConfiguration = "vector-semantic-configuration";
const string embeddingId = "text-embedding-3-small";
const string modelDeploymentId = "gpt-5-mini";
using var cts = new CancellationTokenSource();
var aiClientOptions = new AzureOpenAIClientOptions
{
RetryPolicy = new ClientRetryPolicy()
};
var client = new AzureOpenAIClient(new Uri(openAiEndpoint), new ApiKeyCredential(openAiKey), aiClientOptions);
var chatCompletionsOptions = new ChatCompletionOptions
{
MaxOutputTokenCount = 500,
};
#pragma warning disable AOAI001
// the actual values do not matter here, it's only populated to trigger the exception
var chatDataSource = new AzureSearchChatDataSource
{
Endpoint = new Uri(searchEndpoint),
IndexName = indexName,
InScope = true,
QueryType = DataSourceQueryType.VectorSemanticHybrid,
Authentication = DataSourceAuthentication.FromApiKey(searchKey),
SemanticConfiguration = semanticConfiguration,
VectorizationSource = DataSourceVectorizer.FromDeploymentName(embeddingId)
};
chatCompletionsOptions.AddDataSource(chatDataSource); // this triggers the exception
chatCompletionsOptions.SetNewMaxCompletionTokensPropertyEnabled();
#pragma warning restore AOAI001
var chatClient = client.GetChatClient(modelDeploymentId);
var systemChatMessage = new SystemChatMessage("You're a nice AI agent.");
var userMessage = new UserChatMessage("Hello World");
// this will now throw, enable break on all Exceptions,so it breaks already on the System.InvalidOperationException
// 'The requested operation requires an element of type 'String', but the target element has type 'Number'.'
var completion = await chatClient.CompleteChatAsync([systemChatMessage, userMessage], chatCompletionsOptions, cts.Token).ConfigureAwait(false);
}
}
}