microsoft/semantic-kernel · error · InvalidCastException

The option key '{key}' value must be of type '{typeof(T?)}'

Error message

The option key '{key}' value must be of type '{typeof(T?)}' but is '{value.GetType()}'.

What it means

Thrown by AgentToolDefinitionExtensions.GetOption<T> when Convert.ChangeType fails to convert the stored option value to the requested type T. The method reads a value from the tool definition's Options dictionary and attempts a runtime conversion; if the types are incompatible (e.g., storing a string but requesting int), the inner InvalidCastException from ChangeType is re-thrown with a descriptive message.

Source

Thrown at dotnet/src/Agents/Abstractions/Extensions/AgentToolDefinitionExtensions.cs:39

    public static T? GetOption<T>(this AgentToolDefinition agentToolDefinition, string key)
    {
        Verify.NotNull(agentToolDefinition);
        Verify.NotNull(key);

        if (agentToolDefinition.Options?.TryGetValue(key, out var value) ?? false)
        {
            if (value == null)
            {
                return default;
            }

            try
            {
                return (T?)Convert.ChangeType(value, typeof(T));
            }
            catch (InvalidCastException ex)
            {
                throw new InvalidCastException($"The option key '{key}' value must be of type '{typeof(T?)}' but is '{value.GetType()}'.", ex);
            }
        }

        return default;
    }
}

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Check the agent tool definition file for the offending key and ensure its value matches the expected type.
  2. Use GetOption<string> and parse manually if the source format is unreliable.
  3. Validate option values at load time against the expected schema before calling GetOption<T>.
  4. Inspect the full exception message which includes the key, expected type (T), and actual value type.

Example fix

// before — definition has "top_k": "5" (string)
int topK = tool.GetOption<int>("top_k"); // throws

// after — fix the definition to use a number
// "top_k": 5
int topK = tool.GetOption<int>("top_k");
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check option type before calling GetOption<T>
if (tool.Options?.TryGetValue(key, out var raw) == true && raw is not null)
{
    if (typeof(T) == typeof(int) && raw is not int and not long and not double)
        throw new InvalidOperationException($"Key '{key}' is not numeric.");
}

Try / catch

try
{
    int value = tool.GetOption<int>("top_k");
}
catch (InvalidCastException ex)
{
    _logger.LogError("Type mismatch for option: {Message}", ex.Message);
    // Fall back to string and parse
    var strValue = tool.GetOption<string>("top_k");
    int value = int.Parse(strValue!);
}

Prevention

When it happens

Trigger: Calling GetOption<T>(key) where the stored value's runtime type cannot be converted to T via Convert.ChangeType. For example, GetOption<int>("top_k") when the option was loaded from JSON as a string like "five" instead of the number 5, or GetOption<string> on a value that is a nested object.

Common situations: Agent/tool definition JSON/YAML loaded with values of the wrong scalar type (strings where numbers are expected). Schema drift where a field type changed between definition versions. Parsing issues where a JSON number is deserialized as double but int is requested (though ChangeType handles this), or truly incompatible types like bool to Guid.

Related errors


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