microsoft/aspire · error · ArgumentException

Cannot set nested manifest field

Error message

Cannot set nested manifest field '{path}' because '{segment}' already has a scalar value.

What it means

SetField walks the dotted path through nested dictionaries of the manifest. If an intermediate segment exists but holds a scalar (non-dictionary) value, deeper nesting is impossible, so it throws ArgumentException naming the offending path and segment.

Solutions

  1. Remove or change the earlier WithField call that assigned a scalar to the conflicting segment so it can hold a nested object.
  2. Restructure the field paths so each key is consistently either a leaf value or a parent object.
  3. If the value should be an object, set the full nested value in a single call at the parent path instead of nesting beneath a scalar.

Example fix

// before
resource.WithField("spec.replicas", 3);
resource.WithField("spec.replicas.min", 1); // throws
// after
resource.WithField("spec.replicas", new Dictionary<string, object?> { ["min"] = 1 });
Defensive patterns

Strategy: validation

Validate before calling

static bool IsScalarConflict(IEnumerable<string> appliedPaths, string newPath)
{
    var segments = newPath.Split('.');
    return appliedPaths.Any(p =>
    {
        var s = p.Split('.');
        return s.Length < segments.Length && s.SequenceEqual(segments.Take(s.Length));
    });
}

Type guard

static bool CanNest(object? existing) => existing is null or Dictionary<string, object?>;

Try / catch

try
{
    resource.WithField(path, value);
}
catch (ArgumentException ex) when (ex.Message.Contains("already has a scalar value"))
{
    // A previous WithField assigned a scalar on this prefix; restructure the paths.
}

Prevention

When it happens

Trigger: Calling WithField("spec.replicas.count", 3) after "spec.replicas" was previously set to a scalar like 3 via WithField("spec.replicas", 3); any path that conflicts with an earlier scalar assignment on the same prefix.

Common situations: Multiple WithField calls where one treats a key as an object and another as a value; merging field overrides from config where the same prefix is assigned different shapes.

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

Appendix: source

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

        {
            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));
                }

                current = childFields;
            }
            else
            {
                var childFields = new Dictionary<string, object?>(StringComparer.Ordinal);
                current[segment] = childFields;
                current = childFields;
            }
        }

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

    internal static object? NormalizeManifestValue(object? value)
    {
        return value switch

View on GitHub (pinned to 25830f84bd)