microsoft/aspire · error · InvalidCastException
Cannot cast ' ' from ' ' to
Error message
Cannot cast '{paramName}' from '{value?.GetType().ToString() ?? "null"}' to '{typeof(T)}' What it means
Guard.ThrowIfNotOfType<T> performs a cast and throws InvalidCastException when the supplied object is null or not assignable to T, with a message showing the parameter name, the runtime type, and the target type. It is used where the vendored instrumentation expects a strongly-typed payload (e.g. an object box previously stored).
Solutions
- Verify the object's actual runtime type matches T before the call (use `is T`).
- Fix the code that stored the value so it stores the expected type.
- Null-check the value before casting.
- Check for version mismatches between packages that share the object contract.
Example fix
// before
var item = Guard.ThrowIfNotOfType<MyItem>(obj); // obj is actually OtherItem
// after
if (obj is MyItem item) { /* use item */ } else { /* handle mismatch */ } Defensive patterns
Strategy: type-guard
Validate before calling
if (value is not T) throw new InvalidCastException($"Expected {typeof(T)}, got {value?.GetType().Name ?? "null"}"); Type guard
if (value is T typed) { /* use typed */ } else { /* handle mismatch */ } Try / catch
catch (InvalidCastException ex) { log.LogError(ex, "payload type mismatch"); } Prevention
- Use `is T` pattern matching instead of unchecked casts.
- Keep the storage key/type contract in one shared constant/type.
- Null-check before cast.
When it happens
Trigger: Calling Guard.ThrowIfNotOfType<T>(value) where value is null or of an unrelated type; typically when retrieving cached/state objects that were stored under a different type.
Common situations: Two different components storing different types under the same key; an object changed type after a library upgrade; null leaking into an expected non-null slot.
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
- The specified value is not an Int32.
- A of type cannot be assigned to a BicepValue< >.
- aspire: dict getter returned unexpected type %T
- aspire: dict.toObject: unexpected result type %T
- Aspire.Hosting/Dict.toObject only supports string-key…
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/6a36452dbc1b4fa1.
Report an issue: GitHub.
Appendix: source
Thrown at src/Vendoring/OpenTelemetry.Instrumentation.StackExchangeRedis/Shared/Guard.cs:209
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ThrowIfOutOfRange(double value, [CallerArgumentExpression(nameof(value))] string? paramName = null, double min = double.MinValue, double max = double.MaxValue, string? minName = null, string? maxName = null, string? message = null)
{
Range(value, paramName, min, max, minName, maxName, message);
}
/// <summary>
/// Throw an exception if the value is not of the expected type.
/// </summary>
/// <param name="value">The value to check.</param>
/// <param name="paramName">The parameter name to use in the thrown exception.</param>
/// <typeparam name="T">The type attempted to convert to.</typeparam>
/// <returns>The value casted to the specified type.</returns>
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T ThrowIfNotOfType<T>([NotNull] object? value, [CallerArgumentExpression(nameof(value))] string? paramName = null)
{
return value is not T result
? throw new InvalidCastException($"Cannot cast '{paramName}' from '{value?.GetType().ToString() ?? "null"}' to '{typeof(T)}'")
: result;
}
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void Range<T>(T value, string? paramName, T min, T max, string? minName, string? maxName, string? message)
where T : IComparable<T>
{
if (value.CompareTo(min) < 0 || value.CompareTo(max) > 0)
{
var minMessage = minName != null ? $": {minName}" : string.Empty;
var maxMessage = maxName != null ? $": {maxName}" : string.Empty;
var exMessage = message ?? string.Format(
CultureInfo.InvariantCulture,
"Must be in the range: [{0}{1}, {2}{3}]",
min,
minMessage,
max,View on GitHub (pinned to 25830f84bd)