Repository: microsoft/kiota (csharp)

Issue:
KiotaBuilder is incorrectly finding and using Default media types for contentless responses
### What are you generating using Kiota, clients or plugins?

API Client/SDK

### In what context or format are you using Kiota?

Nuget tool

### Client library/SDK language

Csharp

### Describe the bug

As mentioned and exampled in [this discussion](https://github.com/microsoft/kiota/discussions/6411). The content types for the default are found and used for the Accept header in a generated request when they shouldn't be.

### Expected behavior

Accept header isn't provided when calling an API whose definition provides no media type.

### How to reproduce

see [associated discussion](https://github.com/microsoft/kiota/discussions/6411)

### Open API description file

{
	"openapi": "3.0.1",
	"info": {
        "title": "My Api",
        "description": "An example spec with a generational issue",
        "version": "v1",
        "x-framework": {
            "name": "blablabla"
        }
    },
    "servers": [{
            "url": "https://my.exampledomain.com/awesome/api"
        }
    ],
    "security": [{
            "OAuth_1.0_authorization": []
        }
    ],
	"paths": {
		"/data": {
			"post": {
                "tags": ["data"],
                "summary": "Insert data.",
                "requestBody": {
                    "description": "Request body.",
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/data"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "204": {
                        "description": "Inserted record."
                    },
                    "default": {
                        "description": "Error response.",
                        "content": {
                            "application/custom-error": {
                                "schema": {
                                    "$ref": "#/components/schemas/error"
                                }
                            }
                        }
                    }
                }
            }
		}
	},
    "components": {
        "schemas": {
			"error": {
                "type": "object",
                "properties": {
                    "message": {
                        "title": "Error reason",
                        "type": "string",
                        "readOnly": true
                    }
				}
			},
			"data": {
                "type": "object",
                "properties": {
                    "stuff": {
                        "title": "Some Data",
                        "type": "string"
                    },
                    "numberedStuff": {
                        "title": "Some number",
                        "type": "integer",
						"format": "int64"
                    }
				}
			}
		}
	}
}

### Kiota Version

1.24.3

### Latest Kiota version known to work for scenario above?(Not required)

_No response_

### Known Workarounds

_No response_

### Configuration

_No response_

### Debug output

<details><summary>Click to expand log</summary>
```


<log output here>

```
</details>


### Other information

_No response_

Pull request:
fixes #6413

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e2e24fc728..2b4c8b1238 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 ### Changed
 
 - Fixed a bug where Dart properties casing would change for serialization.
+- Fixed a bug where default response definitions were being considered for Media Type selection [#6413](https://github.com/microsoft/kiota/issues/6413)
 
 ## [1.25.1] - 2025-04-03
 
diff --git a/src/Kiota.Builder/Extensions/OpenApiResponsesExtensions.cs b/src/Kiota.Builder/Extensions/OpenApiResponsesExtensions.cs
new file mode 100644
index 0000000000..7441db468c
--- /dev/null
+++ b/src/Kiota.Builder/Extensions/OpenApiResponsesExtensions.cs
@@ -0,0 +1,20 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using Kiota.Builder.CodeDOM;
+using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi.Models.Interfaces;
+
+namespace Kiota.Builder.Extensions;
+public static class OpenApiResponsesExtensions
+{
+    private static readonly HashSet<string> ignorableStatusCodesForMediaTypes = new([
+        ..Enumerable.Range(400, 599).Select(static x => x.ToString(CultureInfo.InvariantCulture)),
+        CodeMethod.ErrorMappingClientRange,
+        CodeMethod.ErrorMappingServerRange,
+        "default"]);
+
+    public static IEnumerable<KeyValuePair<string, IOpenApiResponse>> WhereValidForMediaTypeSelection(this OpenApiResponses responses)
+        => responses.Where(static x => !ignorableStatusCodesForMediaTypes.Contains(x.Key) && x.Value.Content is not null);
+}
diff --git a/src/Kiota.Builder/KiotaBuilder.cs b/src/Kiota.Builder/KiotaBuilder.cs
index 1b1ccef69d..e840da77a3 100644
--- a/src/Kiota.Builder/KiotaBuilder.cs
+++ b/src/Kiota.Builder/KiotaBuilder.cs
@@ -1233,6 +1233,7 @@ openApiExtension is OpenApiPrimaryErrorMessageExtension primaryErrorMessageExten
     }
     private const string RequestBodyPlainTextContentType = "text/plain";
     private const string RequestBodyOctetStreamContentType = "application/octet-stream";
+    private const string DefaultResponseIndicator = "default";
     private static readonly HashSet<string> redirectStatusCodes = new(StringComparer.OrdinalIgnoreCase) { "301", "302", "303", "307" };
     private static readonly HashSet<string> noContentStatusCodes = new(redirectStatusCodes, StringComparer.OrdinalIgnoreCase) { "201", "202", "204", "205", "304" };
     private static readonly HashSet<string> errorStatusCodes = new(Enumerable.Range(400, 599).Select(static x => x.ToString(CultureInfo.InvariantCulture))
@@ -1247,7 +1248,7 @@ private void AddErrorMappingsForExecutorMethod(OpenApiUrlTreeNode currentNode, O
                 AddErrorMappingToExecutorMethod(currentNode, operation, executorMethod, schema, response.Value, response.Key.ToUpperInvariant());
             }
         }
-        if (operation.Responses.TryGetValue("default", out var defaultResponse) && defaultResponse.GetResponseSchema(config.StructuredMimeTypes) is { } errorSchema)
+        if (operation.Responses.TryGetValue(DefaultResponseIndicator, out var defaultResponse) && defaultResponse.GetResponseSchema(config.StructuredMimeTypes) is { } errorSchema)
         {
             if (!executorMethod.HasErrorMappingCode(CodeMethod.ErrorMappingClientRange))
                 AddErrorMappingToExecutorMethod(currentNode, operation, executorMethod, errorSchema, defaultResponse, CodeMethod.ErrorMappingClientRange);
@@ -1447,12 +1448,12 @@ private void CreateOperationMethods(OpenApiUrlTreeNode currentNode, NetHttpMetho
             {
                 (_, true) => [],
                 (null, _) => operation.Responses!
-                                .Where(static x => !errorStatusCodes.Contains(x.Key) && x.Value.Content is not null)
+                                .WhereValidForMediaTypeSelection()
                                 .SelectMany(static x => x.Value.Content!)
                                 .Select(static x => x.Key) //get the successful non structured media types first, with a default 1 priority
                                 .Union(config.StructuredMimeTypes.GetAcceptedTypes(
                                                             operation.Responses!
-                                                            .Where(static x => errorStatusCodes.Contains(x.Key) && x.Value.Content is not null) // get any structured error ones, with the priority from the configuration
+                                                            .WhereValidForMediaTypeSelection()
                                                             .SelectMany(static x => x.Value.Content!) // we can safely ignore unstructured ones as they won't be used in error mappings anyway and the body won't be read
                                                             .Select(static x => x.Key)))
                         .Distinct(StringComparer.OrdinalIgnoreCase),


Test patch:
diff --git a/tests/Kiota.Builder.Tests/Extensions/OpenApiResponsesExtensionsTests.cs b/tests/Kiota.Builder.Tests/Extensions/OpenApiResponsesExtensionsTests.cs
new file mode 100644
index 0000000000..82971aacba
--- /dev/null
+++ b/tests/Kiota.Builder.Tests/Extensions/OpenApiResponsesExtensionsTests.cs
@@ -0,0 +1,54 @@
+﻿using System.Linq;
+using Kiota.Builder.Extensions;
+using Microsoft.OpenApi.Models;
+using Xunit;
+
+namespace Kiota.Builder.Tests.Extensions;
+public class OpenApiResponsesExtensionsTests
+{
+    [Fact]
+    public void WhereValidForMediaTypeSelectionReturnsAllIfNothingToFilterOut()
+    {
+        var sut = CreateWithStatusCodes(["100", "200", "201", "202", "204", "304", "307"]);
+        var result = sut.WhereValidForMediaTypeSelection().ToList();
+        Assert.Equal(7, result.Count);
+        Assert.Equal(["100", "200", "201", "202", "204", "304", "307"], result.Select(r => r.Key));
+    }
+
+    [Fact]
+    public void WhereValidForMediaTypeSelectionRemoves400RangeEntries()
+    {
+        var sut = CreateWithStatusCodes(["200", "304", "400", "469", "499", "4XX"]);
+        var result = sut.WhereValidForMediaTypeSelection().ToList();
+        Assert.Equal(2, result.Count);
+        Assert.Equal(["200", "304"], result.Select(r => r.Key));
+    }
+
+    [Fact]
+    public void WhereValidForMediaTypeSelectionRemoves500RangeEntries()
+    {
+        var sut = CreateWithStatusCodes(["200", "304", "500", "569", "599", "5XX"]);
+        var result = sut.WhereValidForMediaTypeSelection().ToList();
+        Assert.Equal(2, result.Count);
+        Assert.Equal(["200", "304"], result.Select(r => r.Key));
+    }
+
+    [Fact]
+    public void WhereValidForMediaTypeSelectionRemovesDefaultEntry()
+    {
+        var sut = CreateWithStatusCodes(["200", "304", "default"]);
+        var result = sut.WhereValidForMediaTypeSelection().ToList();
+        Assert.Equal(2, result.Count);
+        Assert.Equal(["200", "304"], result.Select(r => r.Key));
+    }
+
+    private OpenApiResponses CreateWithStatusCodes(string[] statusCodes)
+    {
+        var responses = new OpenApiResponses();
+        foreach (var sc in statusCodes)
+        {
+            responses.Add(sc, new OpenApiResponse());
+        }
+        return responses;
+    }
+}