Skip to content

Invalid response_format.json_schema.name when structured output type is generic #5501

@kzu

Description

@kzu

Description

Given a record like public record Movie(string Title, int Year, ...);, when invoking the client with var movies = await client.CompleteAsync<Movie[]>(...) we get an exception:

Unhandled exception. System.ClientModel.ClientResultException: HTTP 400 (invalid_request_error: invalid_value)
Parameter: response_format.json_schema.name

Invalid 'response_format.json_schema.name': string does not match pattern. Expected a string that matches the pattern '^[a-zA-Z0-9_-]+$'.
   at OpenAI.ClientPipelineExtensions.ProcessMessageAsync(ClientPipeline pipeline, PipelineMessage message, RequestOptions options)
   at OpenAI.Chat.ChatClient.CompleteChatAsync(BinaryContent content, RequestOptions options)
   at OpenAI.Chat.ChatClient.CompleteChatAsync(IEnumerable`1 messages, ChatCompletionOptions options, CancellationToken cancellationToken)
   at Microsoft.Extensions.AI.OpenAIChatClient.CompleteAsync(IList`1 chatMessages, ChatOptions options, CancellationToken cancellationToken)
   at Microsoft.Extensions.AI.OpenTelemetryChatClient.CompleteAsync(IList`1 chatMessages, ChatOptions options, CancellationToken cancellationToken)
   at Microsoft.Extensions.AI.LoggingChatClient.CompleteAsync(IList`1 chatMessages, ChatOptions options, CancellationToken cancellationToken)
   at Microsoft.Extensions.AI.ChatClientStructuredOutputExtensions.CompleteAsync[T](IChatClient chatClient, IList`1 chatMessages, JsonSerializerOptions serializerOptions, ChatOptions options, Nullable`1 useNativeJsonSchema, CancellationToken cancellationToken)
   at Program.<Main>$(String[] args) in C:\Code\script\TypedChat.cs:line 39
   at Program.<Main>(String[] args)

Reproduction Steps

var services = new ServiceCollection()
    .AddChatClient(builder => builder
        .Use(new OpenAI.OpenAIClient(configuration["OpenAI:Key"]!).AsChatClient("gpt-4o-mini")))
    .BuildServiceProvider();

var movies = await client.CompleteAsync<Movie[]>("Top 5 movies from Christopher Nolan", useNativeJsonSchema: true);

Console.WriteLine(movies.Length);

public record Movie(string Title, int Year);

If you switch the type to be a wrapper type, things work, such as: public record MoviesResult(Movie[] Movies);.

Note that switching to a non-generic type such as public class Movies : List<Movie> { } also fails, but this time with:

Unhandled exception. System.ClientModel.ClientResultException: HTTP 400 (invalid_request_error: )
Parameter: response_format

Invalid schema for response_format 'Movies': schema must be a JSON Schema of 'type: "object"', got 'type: "array"'.
   at OpenAI.ClientPipelineExtensions.ProcessMessageAsync(ClientPipeline pipeline, PipelineMessage message, RequestOptions options)
   at OpenAI.Chat.ChatClient.CompleteChatAsync(BinaryContent content, RequestOptions options)
   at OpenAI.Chat.ChatClient.CompleteChatAsync(IEnumerable`1 messages, ChatCompletionOptions options, CancellationToken cancellationToken)

In this case, it's due to the fact that OpenAI expects the root schema element to be an object, and the JSON exporter infers it to be an array instead. This can be solved by detecting this situation automatically and using a wrapper type automatically and unwrapping before returning, such as

    public class Values<T>
    {
        public required T Data { get; set; }
    }

Expected behavior

Typed chats work regardless of which T you are using: arrays, lists, dictionaries,etc. should all be supported and work as-is.

Actual behavior

Multiple failure modes depending on what types you are specifying for the result, with many "gotchas" to learn as a consequence. User doesn't fall in the proverbial pit of success :)

Regression?

No response

Known Workarounds

Use "Response" wrapper types always. Very annoying.

Configuration

<PackageReference Include="Microsoft.Extensions.AI" Version="9.0.0-preview.9.24507.7" />
<PackageReference Include="Microsoft.Extensions.AI.OpenAI" Version="9.0.0-preview.9.24507.7" />

SDK: 9.0.100-rc.1.24452.12

Other information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-aiMicrosoft.Extensions.AI librariesbugThis issue describes a behavior which is not expected - a bug.work in progress 🚧

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions