microsoft/semantic-kernel · error · JsonException
Unexpected author role: {role}
Error message
Unexpected author role: {role} What it means
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.
Source
Thrown at dotnet/src/Connectors/Connectors.Google/Core/Gemini/AuthorRoleConverter.cs:35
return null;
}
if (role.Equals("user", StringComparison.OrdinalIgnoreCase))
{
return AuthorRole.User;
}
if (role.Equals("model", StringComparison.OrdinalIgnoreCase))
{
return AuthorRole.Assistant;
}
if (role.Equals("function", StringComparison.OrdinalIgnoreCase))
{
return AuthorRole.Tool;
}
throw new JsonException($"Unexpected author role: {role}");
}
public override void Write(Utf8JsonWriter writer, AuthorRole? value, JsonSerializerOptions options)
{
if (value is null)
{
writer.WriteNullValue();
return;
}
if (value == AuthorRole.Tool)
{
writer.WriteStringValue("function");
}
else if (value == AuthorRole.Assistant)
{
writer.WriteStringValue("model");
}View on GitHub (pinned to c028a0c7dc)
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.
Example fix
null
Defensive patterns
Strategy: try-catch
Validate before calling
null
Type guard
static bool IsValidGeminiRole(string role) =>
role.Equals("user", StringComparison.OrdinalIgnoreCase) ||
role.Equals("model", StringComparison.OrdinalIgnoreCase) ||
role.Equals("function", StringComparison.OrdinalIgnoreCase); Try / catch
try
{
var response = await client.GetChatMessageContentAsync(history, settings, ct);
}
catch (JsonException ex) when (ex.Message.Contains("Unexpected author role"))
{
logger.LogError(ex, "Gemini returned an unrecognized author role. " +
"This may indicate an API version mismatch.");
throw;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Gemini API doesn't support author role: {value}
- Unexpected response from model
- GeminiPart is invalid. One and only one property among Text,
- MaxTokens {maxTokens} is not valid, the value must be greate
- Chat history can't contain only system messages.
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/e99b8f50d106b4e2.
Report an issue: GitHub.