microsoft/semantic-kernel · error · JsonException

Gemini API doesn't support author role: {value}

Error message

Gemini API doesn't support author role: {value}

What it means

Thrown by AuthorRoleConverter.Write (the JSON serialization path) when attempting to serialize an AuthorRole that is not AuthorRole.Tool, AuthorRole.Assistant, or AuthorRole.User. Gemini's API only accepts 'function', 'model', and 'user' as role values, so any other AuthorRole cannot be written.

Source

Thrown at dotnet/src/Connectors/Connectors.Google/Core/Gemini/AuthorRoleConverter.cs:60

            writer.WriteNullValue();
            return;
        }

        if (value == AuthorRole.Tool)
        {
            writer.WriteStringValue("function");
        }
        else if (value == AuthorRole.Assistant)
        {
            writer.WriteStringValue("model");
        }
        else if (value == AuthorRole.User)
        {
            writer.WriteStringValue("user");
        }
        else
        {
            throw new JsonException($"Gemini API doesn't support author role: {value}");
        }
    }
}

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Remove System role messages from the chat history sent to Gemini, or use the Gemini-specific system instruction mechanism if available.
  2. Ensure all messages use AuthorRole.User, AuthorRole.Assistant, or AuthorRole.Tool.
  3. Filter or transform chat history before passing it to the Gemini connector: var filtered = history.Where(m => m.Role is null || m.Role == AuthorRole.User || m.Role == AuthorRole.Assistant || m.Role == AuthorRole.Tool).ToList();

Example fix

// before — System role causes serialization failure
chatHistory.AddMessage(AuthorRole.System, "You are a helpful assistant.");
await geminiClient.GetChatMessageContentAsync(chatHistory);

// after — move system message to GeminiPromptExecutionSettings or omit
var settings = new GeminiPromptExecutionSettings
{
    SystemInstruction = "You are a helpful assistant."
};
await geminiClient.GetChatMessageContentAsync(chatHistory, settings);
Defensive patterns

Strategy: validation

Validate before calling

// Filter out unsupported roles before sending to Gemini
var supportedRoles = new[] { AuthorRole.User, AuthorRole.Assistant, AuthorRole.Tool };
var geminiHistory = new ChatHistory();
foreach (var msg in history)
{
    if (msg.Role == AuthorRole.System)
    {
        // Move to system instruction
        geminiSettings.SystemInstruction = msg.Content;
    }
    else if (msg.Role is null || supportedRoles.Contains(msg.Role))
    {
        geminiHistory.Add(msg);
    }
}

Type guard

static bool IsSupportedGeminiAuthorRole(AuthorRole? role) =>
    role == AuthorRole.User ||
    role == AuthorRole.Assistant ||
    role == AuthorRole.Tool ||
    role is null;

Try / catch

try { await client.GetChatMessageContentAsync(history, settings, ct); }
catch (JsonException ex) when (ex.Message.Contains("doesn't support author role"))
{
    logger.LogError("Unsupported role in history. Supported: User, Assistant, Tool.");
    // Filter and retry
}

Prevention

When it happens

Trigger: Adding a chat history message with a role that is not User, Assistant, or Tool (e.g. AuthorRole.System or a custom role label) and sending it to the Gemini connector. The Write method is invoked when SK serializes the chat history into the Gemini request payload.

Common situations: Using AuthorRole.System in chat history sent to Gemini — Gemini handles system messages via a separate systemInstruction field, not as a role in the contents array. Creating a custom AuthorRole with a label like 'developer' or 'system'. Sharing chat history across multiple connectors where one supports a role Gemini does not.

Related errors


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/1d3ff74f134cff65. Report an issue: GitHub.