{"record":{"id":"f5d196c566d31623","repo":"microsoft/aspire","slug":"error-deserializing-genai-message-content-error-description","errorCode":null,"errorMessage":"Error deserializing GenAI message content.\nError description: {ex.GetType().FullName}: {ex.Message}\nContent description: {description}","messagePattern":"Error deserializing GenAI message content\\.\nError description: (.+?): (.+?)\nContent description: (.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Dashboard/Model/GenAI/GenAIVisualizerDialogViewModel.cs","lineNumber":573,"sourceCode":"                    }\n\n                    var args = GenAIMessageParsingHelper.TryParseStringJsonNode(function.Arguments);\n                    messagePartViewModels.Add(GenAIItemPartViewModel.CreateMessagePart(new ToolCallRequestPart { Name = function.Name, Arguments = args }));\n                }\n            }\n        }\n    }\n\n    private static TValue DeserializeWithErrorHandling<TValue>(string description, string json, JsonTypeInfo<TValue> jsonTypeInfo)\n    {\n        try\n        {\n            return JsonSerializer.Deserialize<TValue>(json, jsonTypeInfo)!;\n        }\n        catch (Exception ex)\n        {\n            // Don't include JSON in exception message because it could contain sensitive data.\n            throw new InvalidOperationException(\n                $\"\"\"\n                Error deserializing GenAI message content.\n                Error description: {ex.GetType().FullName}: {ex.Message}\n                Content description: {description}\n                \"\"\", ex);\n        }\n    }\n\n    private static bool TryMapEventName(string name, [NotNullWhen(true)] out GenAIItemType? type)\n    {\n        type = name switch\n        {\n            \"gen_ai.system.message\" => GenAIItemType.SystemMessage,\n            \"gen_ai.user.message\" => GenAIItemType.UserMessage,\n            \"gen_ai.assistant.message\" => GenAIItemType.AssistantMessage,\n            \"gen_ai.tool.message\" => GenAIItemType.ToolMessage,\n            \"gen_ai.choice\" => GenAIItemType.OutputMessage,\n            _ => null","sourceCodeStart":555,"sourceCodeEnd":591,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Dashboard/Model/GenAI/GenAIVisualizerDialogViewModel.cs#L555-L591","documentation":"DeserializeWithErrorHandling wraps System.Text.Json deserialization of GenAI event content for the visualizer. When deserialization throws, it rethrows InvalidOperationException with the exception type, message, and a content description — deliberately excluding the raw JSON because it may contain sensitive user data. The inner exception retains the root cause.","triggerScenarios":"Calling DeserializeEventContent for GenAI telemetry event bodies whose JSON doesn't match the target type T (wrong union member, missing discriminator, mismatched JSON type), e.g. deserializing a function-call event body as a text content type.","commonSituations":"Mixed schema versions between the emitting SDK and the dashboard; telemetry attributes holding non-JSON or differently shaped strings; viewing traces produced by third-party GenAI instrumentation.","solutions":["Read the Error description line to find the real failure (inner JsonException) and the Content description to see which event was involved","Match the deserialization target type to the event's actual content type before calling DeserializeEventContent","Update the emitting instrumentation or dashboard so both use the same GenAI content schema","Validate/normalize the JSON shape at ingest time if you control the importer"],"exampleFix":"// before\nvar content = JsonSerializer.Deserialize<GenAIEventContent>(json, jsonTypeInfo);\n// after\nusing var doc = JsonDocument.Parse(json);\nif (doc.RootElement.TryGetProperty(\"type\", out var t) &&\n    t.GetString() == \"text\")\n{\n    var content = JsonSerializer.Deserialize<TextContent>(json, textJsonTypeInfo);\n}","handlingStrategy":"try-catch","validationCode":"try { using var _ = JsonDocument.Parse(json); }\ncatch (JsonException) { throw new FormatException($\"Event content '{description}' is not valid JSON.\"); }","typeGuard":"static bool LooksLikeJson(string? s) =>\n    !string.IsNullOrWhiteSpace(s) &&\n    (s.TrimStart().StartsWith('{') || s.TrimStart().StartsWith('['));","tryCatchPattern":"try\n{\n    content = DeserializeEventContent<T>(json, jsonTypeInfo, description);\n}\ncatch (InvalidOperationException ex)\n{\n    logger.LogWarning(ex, \"Failed to deserialize GenAI event content for {Description}.\", description);\n}","preventionTips":["Match the deserialization type to the event's declared content type","Keep emitter SDK and dashboard schema versions aligned","Never assume telemetry attribute strings are valid JSON of the expected shape"],"tags":["json","deserialization","genai","dashboard"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}