microsoft/aspire · error · InvalidOperationException

Expected Int32OrStringV1 but got

Error message

Expected Int32OrStringV1 but got {value?.GetType()}

What it means

IntOrStringConverter.WriteYaml serializes Kubernetes Int32OrString values (quantities like ports or replicas that may be a number or a string). It throws InvalidOperationException when the value handed to the YAML serializer is not an Int32OrStringV1 instance. This is an internal invariant: the converter is registered for a specific type, so receiving anything else means the object graph or converter registration is wrong.

Solutions

  1. Ensure every value assigned to a member serialized with IntOrStringConverter is an Int32OrStringV1 instance (wrap ints/strings with the Int32OrStringV1 implicit conversions or constructor).
  2. Check that the converter is registered (IEventEmitters/IBetterYamlDotNet type resolution) only for typeof(Int32OrStringV1) and not applied to other types.
  3. If the value may legitimately be absent, ensure it is null-handled upstream rather than passed as a foreign type; a null here yields value?.GetType() == null in the message, pointing to an untyped null path.

Example fix

// before
manifest.Spec.Ports[0].TargetPort = 8080; // plain int in a member typed object
// after
manifest.Spec.Ports[0].TargetPort = new Int32OrStringV1(8080);
Defensive patterns

Strategy: type-guard

Validate before calling

if (value is not Int32OrStringV1) throw new ArgumentException($"Expected Int32OrStringV1, got {value?.GetType().Name}");

Type guard

static bool IsValidIntOrString(object? v) => v is Int32OrStringV1;

Try / catch

try { serializer.Serialize(writer, value); } catch (InvalidOperationException ex) when (ex.Message.Contains("Int32OrStringV1")) { /* fix object graph type */ }

Prevention

When it happens

Trigger: Calling WriteYaml via YamlDotNet with the IntOrStringConverter registered for a type, but passing an object that is not Int32OrStringV1 (e.g. a raw int, string, or null) at src/Aspire.Hosting.Kubernetes/Yaml/IntOrStringConverter.cs:60.

Common situations: Custom code serializing a Kubernetes manifest graph where a property was assigned a plain int or string instead of Int32OrStringV1; manually invoking the converter against the wrong type; a custom resource type mimicking Int32OrStringV1 but using a different CLR type.

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

Appendix: source

Thrown at src/Aspire.Hosting.Kubernetes/Yaml/IntOrStringConverter.cs:60

        var value = scalar.Value;
        parser.MoveNext();

        return string.IsNullOrEmpty(value) ? null : new Int32OrStringV1(value);
    }

    /// <summary>
    /// Writes the given object to the provided YAML emitter using the appropriate format.
    /// </summary>
    /// <param name="emitter">The emitter used to write the YAML output.</param>
    /// <param name="value">The object to be serialized. Expected to be of type <see cref="Int32OrStringV1"/>.</param>
    /// <param name="type">The type of the object being serialized.</param>
    /// <param name="serializer">The serializer to be used for complex object serialization.</param>
    /// <exception cref="InvalidOperationException">Thrown when the provided value is not of type <see cref="Int32OrStringV1"/>.</exception>
    public void WriteYaml(IEmitter emitter, object? value, Type type, ObjectSerializer serializer)
    {
        if (value is not Int32OrStringV1 obj)
        {
            throw new InvalidOperationException($"Expected {nameof(Int32OrStringV1)} but got {value?.GetType()}");
        }

        if (obj.Number != null)
        {
            serializer(obj.Number);
        }
        else
        {
            var val = obj.Value ?? string.Empty;
            serializer(val);
        }
    }
}

View on GitHub (pinned to 25830f84bd)