microsoft/aspire · error · InvalidCastException

The specified value is not an Int32.

Error message

The specified value is not an Int32.

What it means

Thrown by the explicit operator int on Int32OrStringV1 (used for Kubernetes quantity-like values that can be either a number or a string) when the underlying value is a string rather than an int. The explicit cast is documented to throw InvalidCastException if the value isn't a valid integer.

Solutions

  1. Check value.Number.HasValue before casting, or read the string form instead
  2. Use the string cast/property when the value may be non-numeric
  3. Parse the underlying string to int with int.TryParse when a numeric interpretation is needed
  4. Ensure the value was constructed with the integer overload if an int is required downstream

Example fix

// before
int port = (int)value; // throws if value is a string
// after
int port = value.Number ?? int.Parse(value.String, CultureInfo.InvariantCulture);
Defensive patterns

Strategy: type-guard

Validate before calling

if (!value.Number.HasValue) throw new InvalidOperationException($"Expected numeric value, got string '{value.String}'");

Type guard

static bool TryAsInt(Int32OrStringV1 v, out int i) { i = v.Number ?? default; return v.Number.HasValue; }

Try / catch

try { int port = (int)value; }
catch (InvalidCastException) { /* read the string form or parse it */ }

Prevention

When it happens

Trigger: Explicitly casting (int)someInt32OrStringV1 when the value was constructed from a string (e.g. Int32OrStringV1.Parse("6379") with a non-numeric or string-held value), such as a port value that was specified as a string.

Common situations: Ports or quantities configured from config files/user input where the value came in as a string; casting after reading a value that the K8s model intentionally allows as a named string (e.g. port names); copying code that assumed the numeric form.

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/e449755a0d9adbcf. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting.Kubernetes/Resources/Int32OrStringV1.cs:70

    /// <param name="other">The string to compare with.</param>
    /// <returns>True if the current instance is equal to the other string; otherwise, false.</returns>
    public bool Equals(string? other) =>
        Text == other;

    /// <summary>
    /// Returns a string representation of the current instance.
    /// </summary>
    /// <returns>The string representation of the value.</returns>
    public override string? ToString() => Value;

    /// <summary>
    /// Gets the value as a 32-bit integer.
    /// </summary>
    /// <param name="value">The value to get.</param>
    /// <returns></returns>
    /// <exception cref="InvalidCastException">Thrown if the value isn't a valid integer.</exception>
    public static explicit operator int(Int32OrStringV1 value) =>
        value.Number ?? throw new InvalidCastException("The specified value is not an Int32.");

    /// <summary>
    /// Gets the value as a string.
    /// </summary>
    /// <param name="value">The value to get.</param>
    /// <returns>The value as a string.</returns>
    public static explicit operator string?(Int32OrStringV1? value) =>
        value?.Text ?? value?.Number?.ToString(CultureInfo.InvariantCulture);

    /// <summary>
    /// Gets the integer value as a Int32OrStringV1 instance.
    /// </summary>
    /// <param name="value">The integer to get.</param>
    /// <returns>An Int32OrStringV1 instance representing the integer value.</returns>
    public static implicit operator Int32OrStringV1(int value)
    {
        return new(value);
    }

View on GitHub (pinned to 25830f84bd)