microsoft/aspire · error · InvalidCastException

Cannot cast ' ' from ' ' to

Error message

Cannot cast '{paramName}' from '{value?.GetType().ToString() ?? "null"}' to '{typeof(T)}'

What it means

Thrown by Guard.ThrowIfNotOfType<T> in the vendored ConfluentKafka instrumentation's Guard helper when the supplied object cannot be cast to the expected type T. It throws InvalidCastException naming the argument, its actual runtime type, and the target type. Used to validate downcasts of loosely typed payloads or options.

Solutions

  1. Read the actual type from the exception message and construct/pass an instance of the expected type T instead.
  2. Check for package version mismatches where two assemblies disagree on the options type.
  3. Use pattern matching (obj is T t) at the call site to handle mismatches explicitly before calling.

Example fix

// before
object opts = new SqlServerOptions();
Guard.ThrowIfNotOfType<KafkaOptions>(opts);

// after
object opts = new KafkaOptions();
var kafkaOpts = Guard.ThrowIfNotOfType<KafkaOptions>(opts);
Defensive patterns

Strategy: type-guard

Validate before calling

if (value is not T expected)
{
    throw new ArgumentException($"expected {typeof(T)}, got {value?.GetType()}", nameof(value));
}

Type guard

static bool IsOfType<T>([NotNullWhen(true)] object? value, [NotNullWhen(true)] out T? typed) where T : class
{
    typed = value as T;
    return typed is not null;
}

Try / catch

try
{
    instrumented.WithOptions(opts);
}
catch (InvalidCastException ex)
{
    logger.LogError(ex, "options object had the wrong type; check package version alignment");
}

Prevention

When it happens

Trigger: Passing an object to a generic API expecting a specific type T, e.g. an options/state object of the wrong concrete type, or an object[]/object payload that is not T.

Common situations: Passing an incompatible options class after an API change or version mismatch of instrumentation packages; sharing one state object across APIs that expect different types; deserialized payloads typed as object.

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


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/b8962df2377121f6. Report an issue: GitHub.

Appendix: source

Thrown at src/Vendoring/OpenTelemetry.Instrumentation.ConfluentKafka/Shared/Guard.cs:179

        public static void ThrowIfOutOfRange(double value, [CallerArgumentExpression("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("value")] string? paramName = null)
        {
            if (value is not T result)
            {
                throw new InvalidCastException($"Cannot cast '{paramName}' from '{value?.GetType().ToString() ?? "null"}' to '{typeof(T)}'");
            }

            return 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,

View on GitHub (pinned to 25830f84bd)