microsoft/aspire · error · ArgumentException

Use the dedicated manifest API to configure apiVersion…

Error message

Use the dedicated manifest API to configure apiVersion, kind, and metadata fields.

What it means

ParseFieldPath rejects field paths whose first segment is apiVersion, kind, or metadata. Those parts of a Kubernetes manifest are managed by the dedicated manifest API (WithApiVersion/WithKind/metadata settings), so overriding them via generic field paths is disallowed to keep the manifest consistent.

Solutions

  1. Use WithKind and WithApiVersion (or the equivalent dedicated manifest API) to set kind and apiVersion.
  2. Use the dedicated metadata API (e.g. WithLabel/WithAnnotation style methods) instead of paths under "metadata".
  3. Reserve WithField for fields under spec or other non-reserved top-level segments.

Example fix

// before
resource.WithField("metadata.labels.app", "web");
// after
resource.WithLabel("app", "web");
Defensive patterns

Strategy: validation

Validate before calling

var reserved = new[] { "apiVersion", "kind", "metadata" };
if (reserved.Contains(path.Split('.', StringSplitOptions.RemoveEmptyEntries).FirstOrDefault()))
{
    throw new ArgumentException($"Field path '{path}' targets reserved manifest fields; use the dedicated manifest API.", nameof(path));
}

Type guard

static bool IsReservedManifestPath(string path) =>
    path.Split('.', StringSplitOptions.RemoveEmptyEntries).FirstOrDefault() is "apiVersion" or "kind" or "metadata";

Try / catch

try
{
    resource.WithField(path, value);
}
catch (ArgumentException ex) when (ex.Message.Contains("dedicated manifest API"))
{
    // Route apiVersion/kind/metadata updates through WithApiVersion/WithKind/label APIs
}

Prevention

When it happens

Trigger: Calling WithField("apiVersion", ...), WithField("kind", ...), or any path starting with "metadata" (e.g. "metadata.labels.app") on a Kubernetes manifest resource.

Common situations: Porting raw YAML patch code where labels/annotations were set under metadata; developers assuming WithField is a universal JSON-patch mechanism.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

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

        SetField(Fields, segments, path, NormalizeManifestValue(value));

        return this;
    }

    private static string[] ParseFieldPath(string path)
    {
        ArgumentException.ThrowIfNullOrWhiteSpace(path);

        var segments = path.Split('.', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
        if (segments.Length == 0)
        {
            throw new ArgumentException("Manifest field path must contain at least one segment.", nameof(path));
        }

        if (segments[0] is "apiVersion" or "kind" or "metadata")
        {
            throw new ArgumentException("Use the dedicated manifest API to configure apiVersion, kind, and metadata fields.", nameof(path));
        }

        return segments;
    }

    private static void SetField(Dictionary<string, object?> fields, ReadOnlySpan<string> segments, string path, object? value)
    {
        var current = fields;

        for (var i = 0; i < segments.Length - 1; i++)
        {
            var segment = segments[i];
            if (current.TryGetValue(segment, out var child))
            {
                if (child is not Dictionary<string, object?> childFields)
                {
                    throw new ArgumentException($"Cannot set nested manifest field '{path}' because '{segment}' already has a scalar value.", nameof(path));
                }

View on GitHub (pinned to 25830f84bd)