microsoft/aspire · error · TypeError
Invalid type for option
Error message
Invalid type for option '{optionName}'. Expected: {String.Join(" or ", variations.Select(v => v.OptionType.Replace("typing.", "")))} What it means
This TypeError is raised by generated Python builder overloads when the argument passed for a positional option (e.g. the value feeding an option-style capability variant) does not match any of the accepted variation types for that option. The generator emits a chain of isinstance-based branches, and this is the terminal `else` branch reached when none matched. The expected type names are derived from the ATS variation metadata, so the message lists the exact accepted types.
Solutions
- Read the 'Expected: ...' list in the message and convert the argument to one of the listed types (e.g. str(...), int(...), or the documented option wrapper type).
- Check the generated signature/docs for the option to confirm which wrapper or primitive types are accepted.
- If the value comes from dynamic input, add an explicit validation/conversion step before the call.
- Regenerate the Python module if the source contract changed so variants and call sites are consistent.
Example fix
// before opts = builder.with_option(config_value) # config_value came from JSON as int // after opts = builder.with_option(str(config_value)) # expected type is str
Defensive patterns
Strategy: type-guard
Validate before calling
if not isinstance(config_value, (str, bool)):
config_value = str(config_value)
builder.with_option(config_value) Type guard
def is_valid_option(value, accepted=(str, bool)):
return isinstance(value, accepted) Try / catch
try:
result = builder.with_option(value)
except TypeError as e:
log.error("option type rejected: %s", e)
raise Prevention
- Coerce dynamic (JSON/env) inputs to declared types before calling generated constructors.
- Read the generated function signature/docs for each option's accepted types.
- Regenerate the module whenever the source contract changes.
When it happens
Trigger: Calling a generated option-constructor function (e.g. a builder variant selected by optionIndex) and passing a value whose runtime type is not one of the declared variation types, e.g. passing a raw string where a typed option wrapper is expected, or passing int where 'str or bool' is accepted.
Common situations: Hand-editing generated calls; using dynamic data (parsed JSON, env vars) whose type differs from the declared option type; Python 2/str-vs-bytes or int/float mismatches; upgrading the source package so an option's allowed types changed while call sites were not updated.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Command line args must be strings
- Model must be a FoundryModel or a string model name.
- TYPE_MISMATCH
- A of type cannot be assigned to a BicepValue< >.
- Array params contains empty item
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/93f092e02fa70761.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.CodeGeneration.Python/AtsPythonCodeGenerator.cs:2773
builder.AppendLine(CultureInfo.InvariantCulture, $" rpc_args[\"{param.Name}\"] = {paramHandler}");
}
builder.AppendLine(CultureInfo.InvariantCulture, $" handle = self._wrap_builder(client.invoke_capability('{variationCapabilityId}', rpc_args))");
}
else // Single parameter
{
builder.AppendLine(CultureInfo.InvariantCulture, $" {clause} _validate_type(_{optionName}, {currentOption}):");
builder.AppendLine(CultureInfo.InvariantCulture, $" rpc_args: dict[str, typing.Any] = {{\"{targetParamName}\": handle}}");
var singleParam = requiredParameters.Count > 0
? requiredParameters[0]
: optionalParameters[0];
var paramHandler = GetConstructorParamHandler(singleParam, $"typing.cast({currentOption}, _{optionName})");
builder.AppendLine(CultureInfo.InvariantCulture, $" rpc_args[\"{singleParam.Name}\"] = {paramHandler}");
builder.AppendLine(CultureInfo.InvariantCulture, $" handle = self._wrap_builder(client.invoke_capability('{variationCapabilityId}', rpc_args))");
}
if (last)
{
builder.AppendLine(CultureInfo.InvariantCulture, $" else:");
builder.AppendLine(CultureInfo.InvariantCulture, $" raise TypeError(\"Invalid type for option '{optionName}'. Expected: {String.Join(" or ", variations.Select(v => v.OptionType.Replace("typing.", "")))}\")");
}
else
{
BuildOptionConstructor(builder, capability, optionName, variations, mergedDispatch, optionIndex + 1);
}
}
/// <summary>
/// Generates a callback type signature for Python.
/// </summary>
private string GenerateCallbackTypeSignature(IReadOnlyList<AtsCallbackParameterInfo>? parameters, AtsTypeRef? returnType)
{
var paramTypes = parameters?.Select(p => MapTypeRefToPython(p.Type)).ToList() ?? [];
var returnTypeStr = returnType != null ? MapTypeRefToPython(returnType) : "None";
if (paramTypes.Count == 0)
{View on GitHub (pinned to 25830f84bd)