{"record":{"id":"b468681c4fc22d7d","repo":"microsoft/autogen","slug":"exception-of-type-system-text-json-jsonexception","errorCode":null,"errorMessage":"Exception of type 'System.Text.Json.JsonException' was thrown.","messagePattern":"Exception of type 'System\\.Text\\.Json\\.JsonException' was thrown\\.","errorType":"exception","errorClass":"JsonException","httpStatus":null,"severity":"error","filePath":"dotnet/src/AutoGen.WebAPI/OpenAI/Converter/OpenAIMessageConverter.cs","lineNumber":22,"sourceCode":"using System;\nusing System.Text.Json;\nusing System.Text.Json.Serialization;\n\nnamespace AutoGen.WebAPI.OpenAI.DTO;\n\ninternal class OpenAIMessageConverter : JsonConverter<OpenAIMessage>\n{\n    public override OpenAIMessage Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)\n    {\n        using JsonDocument document = JsonDocument.ParseValue(ref reader);\n        var root = document.RootElement;\n        var role = root.GetProperty(\"role\").GetString();\n        var contentDocument = root.GetProperty(\"content\");\n        var isContentDocumentString = contentDocument.ValueKind == JsonValueKind.String;\n        switch (role)\n        {\n            case \"system\":\n                return JsonSerializer.Deserialize<OpenAISystemMessage>(root.GetRawText()) ?? throw new JsonException();\n            case \"user\" when isContentDocumentString:\n                return JsonSerializer.Deserialize<OpenAIUserMessage>(root.GetRawText()) ?? throw new JsonException();\n            case \"user\" when !isContentDocumentString:\n                return JsonSerializer.Deserialize<OpenAIUserMultiModalMessage>(root.GetRawText()) ?? throw new JsonException();\n            case \"assistant\":\n                return JsonSerializer.Deserialize<OpenAIAssistantMessage>(root.GetRawText()) ?? throw new JsonException();\n            case \"tool\":\n                return JsonSerializer.Deserialize<OpenAIToolMessage>(root.GetRawText()) ?? throw new JsonException();\n            default:\n                throw new JsonException();\n        }\n    }\n\n    public override void Write(Utf8JsonWriter writer, OpenAIMessage value, JsonSerializerOptions options)\n    {\n        switch (value)\n        {\n            case OpenAISystemMessage systemMessage:","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/dotnet/src/AutoGen.WebAPI/OpenAI/Converter/OpenAIMessageConverter.cs#L4-L40","documentation":"In OpenAIMessageConverter.Read, a message with role 'system' that fails to deserialize into OpenAISystemMessage (Deserialize returns null or its required members are missing) produces a bare JsonException. This converter fronts the OpenAI-compatible WebAPI endpoint, so the exception surfaces as HTTP deserialization failure of the request body.","triggerScenarios":"POSTing to the WebAPI chat-completions endpoint a JSON message with \"role\":\"system\" whose payload does not match OpenAISystemMessage's expected shape (e.g. missing required properties, wrong casing without the matching serializer options).","commonSituations":"Third-party clients sending system messages with extra/absent fields, a proxy reformatting the body, or a payload where 'content' is null instead of a string.","solutions":["Send system messages as {\"role\":\"system\",\"content\":\"your system prompt\"} with string content","Validate the request body against the OpenAI chat-completions schema before sending","Catch JsonException in ASP.NET pipeline and return 400 with a meaningful message instead of a 500","Check that no intermediate layer (gateway/middleware) rewrites or strips the content field"],"exampleFix":"// before\n{\"role\":\"system\",\"content\":null}\n\n// after\n{\"role\":\"system\",\"content\":\"You are a helpful assistant.\"}","handlingStrategy":"try-catch","validationCode":"// client-side pre-validation of system messages\nbool IsValidSystemMessage(JsonElement m) =>\n    m.GetProperty(\"role\").GetString() == \"system\"\n    && m.GetProperty(\"content\").ValueKind == JsonValueKind.String;","typeGuard":"static bool IsSystemMessage(JsonElement m) =>\n    m.TryGetProperty(\"role\", out var r) && r.GetString() == \"system\";","tryCatchPattern":"try { await httpClient.PostAsJsonAsync(\"/v1/chat/completions\", body); }\ncatch (JsonException ex)\n{\n    // server-side: map to 400 with position info\n    return BadRequest($\"Malformed system message at position {ex.LineNumber}:{ex.BytePositionInLine}\");\n}","preventionTips":["Schema-validate request bodies against the OpenAI chat-completions JSON schema before submitting","Keep system message content a plain JSON string","Log the exact failing message index during development via middleware"],"tags":["csharp","json","webapi","openai-compatible","deserialization"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}