Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

[BUG][csharp] httpclient: oneOf/anyOf responses throw ArgumentException because FromJson is invoked with HttpContent

Closed Beginner friendly
#25,079 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

@cguldner is already working on this.

Since Oct 1, 2026.

  • #25080 by @cguldner — open

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
78/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
csharp
Domain
api, tooling

Research direction

Start in modules/openapi-generator/src/main/resources/csharp/libraries/httpclient/ApiClient.mustache around the AbstractOpenAPISchema handling in ApiClient.ExecAsync. Generate the provided Pets specification with the csharp httpclient library and run the oneOf response reproduction. Done means the generated client returns the Cat instance and no ArgumentException is thrown.

Written by the indexing model from the issue text.

Description

Issue: Bug
Bug Report Checklist
  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator?
  • Have you tested with the latest master to confirm the issue still exists?
  • Have you searched for related issues/PRs?
  • What's the actual output vs expected output?
  • [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

With the csharp generator and --library=httpclient, any operation whose response schema is a oneOf (or anyOf) throws at runtime, even when the server returns a valid response.

After deserializing a successful response, ApiClient.ExecAsync has a special case for AbstractOpenAPISchema types:

object responseData = await deserializer.Deserialize<T>(response).ConfigureAwait(false);

// if the response type is oneOf/anyOf, call FromJSON to deserialize the data
if (typeof(Pets.Model.AbstractOpenAPISchema).IsAssignableFrom(typeof(T)))
{
    responseData = (T)typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content });
}

FromJson(string jsonString) takes a JSON string, but the code passes response.Content, which is an HttpContent. Because the call goes through reflection it compiles, then fails on every call:

Unhandled exception. System.ArgumentException: Object of type 'System.Net.Http.HttpConnectionResponseContent' cannot be converted to type 'System.String'.
   at System.RuntimeType.CheckValue(Object& value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
   at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Pets.Client.ApiClient.ExecAsync[T](HttpRequestMessage req, IReadableConfiguration configuration, CancellationToken cancellationToken)
   at Pets.Client.ApiClient.Exec[T](HttpRequestMessage req, IReadableConfiguration configuration)
   at Pets.Client.ApiClient.Get[T](String path, RequestOptions options, IReadableConfiguration configuration)
   at Pets.Api.DefaultApi.GetPetWithHttpInfo()

This makes every operation with a oneOf/anyOf response unusable with the httpclient library.

openapi-generator version
  • 7.25.0
  • 7.26.0-SNAPSHOT (master, 20261001.032649-175)

Not a recent regression: the same line is in the httpclient ApiClient.mustache at v5.4.0 (csharp-netcore), v6.0.0, v7.0.0, and current master.

OpenAPI declaration file content or url
openapi: 3.0.3
info:
  title: Pets
  version: '1'
paths:
  /pet:
    get:
      operationId: getPet
      responses:
        '200':
          description: A cat or a dog.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Cat'
                  - $ref: '#/components/schemas/Dog'
components:
  schemas:
    Cat:
      type: object
      required: [meows]
      properties:
        meows:
          type: boolean
      additionalProperties: false
    Dog:
      type: object
      required: [barks]
      properties:
        barks:
          type: boolean
      additionalProperties: false

openapi-generator-cli validate -i pets.yaml reports No validation issues detected.

Generation Details
java -jar openapi-generator-cli.jar generate \
  -i pets.yaml \
  -g csharp \
  --library=httpclient \
  -o gen \
  --additional-properties=packageName=Pets

The generated client targets net10.0 and was run on .NET runtime 10.0.12.

Steps to reproduce
  1. Generate the client with the command above.

  2. Serve GET /pet returning {"meows": true} with Content-Type: application/json on http://127.0.0.1:18803.

  3. Run a console program that references the generated project:

    using System;
    using Pets.Api;
    using Pets.Client;
    
    public static class Program
    using Pets.Client;
    
    public static class Program
    {
        public static void Main()
        {
            var api = new DefaultApi(new Configuration { BasePath = "http://127.0.0.1:18803" });
            var pet = api.GetPet();
            Console.WriteLine("OK: " + pet.ActualInstance.GetType().Name);
        }
    }
    

Expected output: OK: Cat

Actual output: the ArgumentException above, thrown from ApiClient.ExecAsync.

Related issues/PRs

I couldn't find an existing report. I searched issues for httpclient FromJson response.Content, HttpConnectionResponseContent cannot be converted, and csharp httpclient oneOf FromJson.

Suggest a fix

The problem is in modules/openapi-generator/src/main/resources/csharp/libraries/httpclient/ApiClient.mustache (line 566 on master):

responseData = (T)typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content });

Passing the body text fixes it. HttpClient has already buffered the content, so it can be read again:

responseData = (T)typeof(T).GetMethod("FromJson").Invoke(null, new object[] { await response.Content.ReadAsStringAsync().ConfigureAwait(false) });

With this change the reproduction above prints OK: Cat.

Removing the block may also work. The Deserialize<T> call just before it already returns the correct type, because each oneOf/anyOf model has a [JsonConverter(typeof(...JsonConverter))] attribute that Newtonsoft.Json uses.

I only ran oneOf responses. The anyOf claim comes from the code: the branch checks AbstractOpenAPISchema, which both kinds of model inherit from. To keep the issue strictly to what was tested, change "oneOf (or anyOf)" to just "oneOf".

Dominant language
Java
Stars
26.8k
Forks
7.7k
Avg merge
2d 14h
Merged PRs (30d)
139

Getting set up

Open in Codespaces

Starts the project's dev container in your browser, under your own GitHub account.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from OpenAPITools/openapi-generator

All issues in OpenAPITools/openapi-generator

Similar issues

More Java issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.