{"record":{"id":"e99b8f50d106b4e2","repo":"microsoft/semantic-kernel","slug":"unexpected-author-role-role","errorCode":null,"errorMessage":"Unexpected author role: {role}","messagePattern":"Unexpected author role: (.+?)","errorType":"exception","errorClass":"JsonException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Connectors/Connectors.Google/Core/Gemini/AuthorRoleConverter.cs","lineNumber":35,"sourceCode":"            return null;\n        }\n\n        if (role.Equals(\"user\", StringComparison.OrdinalIgnoreCase))\n        {\n            return AuthorRole.User;\n        }\n\n        if (role.Equals(\"model\", StringComparison.OrdinalIgnoreCase))\n        {\n            return AuthorRole.Assistant;\n        }\n\n        if (role.Equals(\"function\", StringComparison.OrdinalIgnoreCase))\n        {\n            return AuthorRole.Tool;\n        }\n\n        throw new JsonException($\"Unexpected author role: {role}\");\n    }\n\n    public override void Write(Utf8JsonWriter writer, AuthorRole? value, JsonSerializerOptions options)\n    {\n        if (value is null)\n        {\n            writer.WriteNullValue();\n            return;\n        }\n\n        if (value == AuthorRole.Tool)\n        {\n            writer.WriteStringValue(\"function\");\n        }\n        else if (value == AuthorRole.Assistant)\n        {\n            writer.WriteStringValue(\"model\");\n        }","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/dotnet/src/Connectors/Connectors.Google/Core/Gemini/AuthorRoleConverter.cs#L17-L53","documentation":"Thrown by AuthorRoleConverter.Read (the JSON deserialization path) when the 'role' string in a Gemini response does not match 'user', 'model', or 'function' (case-insensitive comparison). Gemini's API uses these three role strings; anything else cannot be mapped to an SK AuthorRole.","triggerScenarios":"The Gemini API returns a response containing a role string that is not 'user', 'model', or 'function'. This fires during JSON deserialization of chat completion or streaming responses. Case does not matter (OrdinalIgnoreCase), but the literal string must match.","commonSituations":"Google introduces a new role string in a future API version (e.g. 'system' or 'developer'). A proxy or mock server returns responses with incorrect role values. The API returns an error response that partially deserializes as a valid structure but with unexpected field values.","solutions":["Upgrade the Connectors.Google package if Google introduced a new role the connector should support.","If using a mock or proxy, ensure role strings are exactly 'user', 'model', or 'function'.","Catch JsonException when processing Gemini responses to gracefully handle unrecognized roles."],"exampleFix":"null","handlingStrategy":"try-catch","validationCode":"null","typeGuard":"static bool IsValidGeminiRole(string role) =>\n    role.Equals(\"user\", StringComparison.OrdinalIgnoreCase) ||\n    role.Equals(\"model\", StringComparison.OrdinalIgnoreCase) ||\n    role.Equals(\"function\", StringComparison.OrdinalIgnoreCase);","tryCatchPattern":"try\n{\n    var response = await client.GetChatMessageContentAsync(history, settings, ct);\n}\ncatch (JsonException ex) when (ex.Message.Contains(\"Unexpected author role\"))\n{\n    logger.LogError(ex, \"Gemini returned an unrecognized author role. \" +\n        \"This may indicate an API version mismatch.\");\n    throw;\n}","preventionTips":["Keep the Connectors.Google package up to date to handle new roles Google may introduce.","If using a mock server, ensure role strings match Gemini's expected values exactly.","Log raw responses in debug mode to diagnose unexpected role values."],"tags":["google","gemini","json","serialization","role"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}