{"record":{"id":"62463d278a7b152d","repo":"microsoft/semantic-kernel","slug":"the-option-key-key-value-must-be-of-type-typ","errorCode":null,"errorMessage":"The option key '{key}' value must be of type '{typeof(T?)}' but is '{value.GetType()}'.","messagePattern":"The option key '(.+?)' value must be of type '(.+?)' but is '(.+?)'\\.","errorType":"exception","errorClass":"InvalidCastException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Agents/Abstractions/Extensions/AgentToolDefinitionExtensions.cs","lineNumber":39,"sourceCode":"    public static T? GetOption<T>(this AgentToolDefinition agentToolDefinition, string key)\n    {\n        Verify.NotNull(agentToolDefinition);\n        Verify.NotNull(key);\n\n        if (agentToolDefinition.Options?.TryGetValue(key, out var value) ?? false)\n        {\n            if (value == null)\n            {\n                return default;\n            }\n\n            try\n            {\n                return (T?)Convert.ChangeType(value, typeof(T));\n            }\n            catch (InvalidCastException ex)\n            {\n                throw new InvalidCastException($\"The option key '{key}' value must be of type '{typeof(T?)}' but is '{value.GetType()}'.\", ex);\n            }\n        }\n\n        return default;\n    }\n}\n","sourceCodeStart":21,"sourceCodeEnd":46,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/dotnet/src/Agents/Abstractions/Extensions/AgentToolDefinitionExtensions.cs#L21-L46","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check the agent tool definition file for the offending key and ensure its value matches the expected type.","Use GetOption<string> and parse manually if the source format is unreliable.","Validate option values at load time against the expected schema before calling GetOption<T>.","Inspect the full exception message which includes the key, expected type (T), and actual value type."],"exampleFix":"// before — definition has \"top_k\": \"5\" (string)\nint topK = tool.GetOption<int>(\"top_k\"); // throws\n\n// after — fix the definition to use a number\n// \"top_k\": 5\nint topK = tool.GetOption<int>(\"top_k\");","handlingStrategy":"try-catch","validationCode":"// Pre-check option type before calling GetOption<T>\nif (tool.Options?.TryGetValue(key, out var raw) == true && raw is not null)\n{\n    if (typeof(T) == typeof(int) && raw is not int and not long and not double)\n        throw new InvalidOperationException($\"Key '{key}' is not numeric.\");\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    int value = tool.GetOption<int>(\"top_k\");\n}\ncatch (InvalidCastException ex)\n{\n    _logger.LogError(\"Type mismatch for option: {Message}\", ex.Message);\n    // Fall back to string and parse\n    var strValue = tool.GetOption<string>(\"top_k\");\n    int value = int.Parse(strValue!);\n}","preventionTips":["Validate agent definition files against a schema that specifies expected types per option key.","Use GetOption<string> and parse defensively if the definition source is untrusted.","Log the full exception message which names the key, expected type, and actual type."],"tags":["tool-definition","type-conversion","invalidcast","options"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}