microsoft/aspire · error · ArgumentException

Manifest field values must be JSON-compatible primitives…

Error message

Manifest field values must be JSON-compatible primitives, dictionaries, or arrays. Type '{value.GetType()}' is not supported.

What it means

This error means a value passed to a Kubernetes manifest field (via WithField) is not representable as JSON. The library normalizes manifest values to JSON-compatible primitives, dictionaries, and arrays before emitting YAML/JSON, and throws this ArgumentException for any other type. It exists to guarantee the generated manifest is always valid, serializable JSON.

Solutions

  1. Convert the value to a JSON-compatible type before passing it: strings, bools, long/int/double/decimal/float, IDictionary with string keys, or IEnumerable
  2. Convert DateTime/DateTimeOffset to an ISO-8601 string with .ToString("O") before passing
  3. Wrap custom objects in a Dictionary<string, object?> with the desired properties
  4. Serialize the object to JsonNode/JsonElement via JsonSerializer.SerializeToNode and pass that

Example fix

// before
builder.AddKubernetesManifest("svc", manifest => manifest.WithField("spec.metadata.createdAt", DateTime.UtcNow));
// after
builder.AddKubernetesManifest("svc", manifest => manifest.WithField("spec.metadata.createdAt", DateTime.UtcNow.ToString("O")));
Defensive patterns

Strategy: validation

Validate before calling

static bool IsJsonCompatible(object? value) => value is null or string or bool or sbyte or byte or short or ushort or int or uint or long or ulong or float or double or decimal or JsonElement or JsonNode or IDictionary or (IEnumerable and not string);

Type guard

if (value is not (null or string or bool or int or long or double or float or decimal or JsonElement or JsonNode or IDictionary or IEnumerable)) throw new ArgumentException($"Unsupported manifest field type {value.GetType()}");

Try / catch

try { manifest.WithField(path, value); } catch (ArgumentException ex) when (ex.Message.Contains("JSON-compatible")) { /* fall back: serialize value to JsonNode */ }

Prevention

When it happens

Trigger: Calling WithField on a KubernetesManifestResource (or nesting a dictionary/array inside one) with a value whose runtime type is not a string, bool, numeric type, JsonElement, JsonNode, IDictionary, or IEnumerable — e.g. a custom class, DateTime, Guid, or a struct.

Common situations: Developers pass domain objects, DateTime/DateTimeOffset values, or enums directly as field values, assuming auto-conversion. Since manifest fields come from generic object parameters, the compiler cannot catch this; it only fails at manifest generation time.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting.Kubernetes/KubernetesManifestResource.cs:156

        current[segments[^1]] = value;
    }

    internal static object? NormalizeManifestValue(object? value)
    {
        return value switch
        {
            null => null,
            string => value,
            bool => value,
            byte or sbyte or short or ushort or int or uint or long or ulong => value,
            float floatValue => NormalizeFloatingPointValue(floatValue),
            double doubleValue => NormalizeFloatingPointValue(doubleValue),
            decimal decimalValue => NormalizeDecimalValue(decimalValue),
            JsonElement element => NormalizeJsonElement(element),
            JsonNode node => NormalizeJsonNode(node),
            IDictionary dictionary => NormalizeDictionary(dictionary),
            IEnumerable enumerable when value is not string => NormalizeEnumerable(enumerable),
            _ => throw new ArgumentException($"Manifest field values must be JSON-compatible primitives, dictionaries, or arrays. Type '{value.GetType()}' is not supported.", nameof(value))
        };
    }

    private const double MaxLongExclusiveAsDouble = 9_223_372_036_854_775_808d;

    private static object NormalizeFloatingPointValue(float value)
    {
        if (!float.IsFinite(value))
        {
            throw new ArgumentException("Manifest field numeric values must be finite.", nameof(value));
        }

        if (MathF.Truncate(value) == value)
        {
            return ConvertWholeNumberToLong(value);
        }

        return value;

View on GitHub (pinned to 25830f84bd)