{"record":{"id":"d3f3dd791fce0784","repo":"microsoft/aspire","slug":"unexpected-end-of-json-while-skipping-property-value","errorCode":null,"errorMessage":"Unexpected end of JSON while skipping property value.","messagePattern":"Unexpected end of JSON while skipping property value\\.","errorType":"exception","errorClass":"JsonException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Dashboard/Model/GenAI/GenAIMessageParsingHelper.cs","lineNumber":133,"sourceCode":"                    if (!reader.Read())\n                    {\n                        throw new JsonException(\"Unexpected end of JSON while reading role value.\");\n                    }\n                    role = reader.GetString();\n                    break;\n                case \"parts\":\n                    // DeserializeArrayIncrementally reads the StartArray token itself.\n                    (parts, partsTruncated) = DeserializeArrayIncrementally<MessagePart>(ref reader, ReadMessagePart);\n                    break;\n                default:\n                    if (!reader.Read())\n                    {\n                        throw new JsonException(\"Unexpected end of JSON while reading property value.\");\n                    }\n\n                    if (!reader.TrySkip())\n                    {\n                        throw new JsonException(\"Unexpected end of JSON while skipping property value.\");\n                    }\n                    break;\n            }\n        }\n\n        return (role ?? string.Empty, parts ?? [], partsTruncated);\n    }\n\n    /// <summary>\n    /// If the node is a JSON string that parses to a JSON object or array, return the parsed node instead.\n    /// </summary>\n    internal static JsonNode? TryParseStringJsonNode(JsonNode? node)\n    {\n        if (node?.GetValueKind() == JsonValueKind.String && node.GetValue<string>() is { } json)\n        {\n            try\n            {\n                var parsed = JsonNode.Parse(json);","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Dashboard/Model/GenAI/GenAIMessageParsingHelper.cs#L115-L151","documentation":"After reading the value token of an unknown property, ReadChatMessage calls Utf8JsonReader.TrySkip() to bypass nested content. TrySkip returns false when the reader reaches the end of the data before the value's closing token, meaning the JSON is truncated inside a nested object/array, so JsonException is thrown.","triggerScenarios":"An unrecognized property with a nested value (object or array) where the JSON ends before the matching close bracket, e.g. {\"role\":\"user\",\"attachments\":[{\"type\":\"file\"} — with the closing tokens missing.","commonSituations":"Telemetry bodies clipped by attribute length limits in the middle of nested structures; partially written log files; copy/paste truncation of payloads during debugging.","solutions":["Check that the recorded body is complete — compare against the original telemetry payload length","Increase exporter/dashboard body size limits (OTEL attribute value length limits) so nested content is not cut","Pre-validate with JsonDocument.Parse to reject truncated payloads with a clearer message","Wrap the parse call so the entry renders as unparseable instead of breaking the visualizer"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"using var doc = JsonDocument.Parse(json); // Parse fully validates nesting; a truncated nested value throws here first\nif (doc.RootElement.ValueKind != JsonValueKind.Object)\n    throw new FormatException(\"Chat message must be a complete JSON object.\");","typeGuard":"static bool IsWellFormedJsonObject(string json)\n{\n    try { using var d = JsonDocument.Parse(json); return d.RootElement.ValueKind == JsonValueKind.Object; }\n    catch (JsonException) { return false; }\n}","tryCatchPattern":"try { ParseChatMessage(json); }\ncatch (JsonException ex) when (ex.Message.Contains(\"skipping property value\"))\n{\n    logger.LogWarning(\"GenAI message nested value truncated: {Message}\", ex.Message);\n}","preventionTips":["Verify exported attribute length limits cover nested arrays/objects end to end","Never truncate payloads by raw byte slicing — serialize complete structures only","Run a full JSON parse as a pre-flight gate before reader-based parsing"],"tags":["json","truncated-input","genai","parsing"],"backgroundTag":"json-parse-error","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"}