microsoft/aspire · error · InvalidOperationException

Cannot add secret parameter

Error message

Cannot add secret parameter '{value.Resource.Name}' as build argument '{name}' while configuring resource '{builder.Resource.Name}'. Use WithBuildSecret instead.

What it means

WithBuildArg(IResourceBuilder<ParameterResource>, ...) rejects parameter resources marked as secret. Secret values must not be baked into image layers by Docker build args, so the library throws this InvalidOperationException and directs you to WithBuildSecret, which passes the value securely via build secrets.

Solutions

  1. Replace WithBuildArg with WithBuildSecret(name, secretParameter) so the value is mounted as a build secret instead of an ARG.
  2. Keep the secret out of the Dockerfile ARG/RUN chain; use BuildKit's --secret and RUN --mount=type=secret in the Dockerfile.
  3. If the value is not actually sensitive, create the parameter with secret: false and keep using WithBuildArg.
  4. exampleFix placeholder

Example fix

// before
.WithBuildArg("API_TOKEN", tokenParam); // tokenParam is a secret parameter
// after
.WithBuildSecret("API_TOKEN", tokenParam);
Defensive patterns

Strategy: validation

Validate before calling

if (value is IResourceBuilder<ParameterResource> p && p.Resource.Secret)
    throw new InvalidOperationException($"Use WithBuildSecret instead of WithBuildArg for secret parameter '{p.Resource.Name}'.");

Try / catch

try
{
    resource.WithBuildArg(name, paramBuilder);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("Use WithBuildSecret instead"))
{
    // Switch to WithBuildSecret and retry
}

Prevention

When it happens

Trigger: Calling WithBuildArg(name, builder.AddParameter(...)) where the parameter was created as secret (AddParameter(name, secret: true) or WithConnectionSecret etc.).

Common situations: Passing API keys, tokens, or passwords as build args; reusing a secret connection-string parameter as a build argument; converting an existing plain build arg to a secret without switching APIs.

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

Appendix: source

Thrown at src/Aspire.Hosting/ContainerResourceBuilderExtensions.cs:1205

    ///
    /// builder.AddContainer("mycontainer", "myimage")
    ///        .WithDockerfile("../mycontainer")
    ///        .WithBuildArg("CUSTOM_BRANDING", branding);
    ///
    /// builder.Build().Run();
    /// </code>
    /// </example>
    /// </remarks>
    [AspireExportIgnore(Reason = "Polyglot AppHosts use the union-based withBuildArg dispatcher export.")]
    public static IResourceBuilder<T> WithBuildArg<T>(this IResourceBuilder<T> builder, string name, IResourceBuilder<ParameterResource> value) where T : ContainerResource
    {
        ArgumentNullException.ThrowIfNull(builder);
        ArgumentNullException.ThrowIfNull(name);
        ArgumentNullException.ThrowIfNull(value);

        if (value.Resource.Secret)
        {
            throw new InvalidOperationException($"Cannot add secret parameter '{value.Resource.Name}' as build argument '{name}' while configuring resource '{builder.Resource.Name}'. Use WithBuildSecret instead.");
        }

        return builder.WithBuildArg(name, value.Resource);
    }

    /// <summary>
    /// Adds a build argument when the container is built from a Dockerfile.
    /// </summary>
    /// <typeparam name="T">The type of container resource.</typeparam>
    /// <param name="builder">The resource builder for the container resource.</param>
    /// <param name="name">The name of the build argument.</param>
    /// <param name="value">The build argument value, either a string or a parameter resource.</param>
    /// <returns>The <see cref="IResourceBuilder{T}"/>.</returns>
    /// <ats-returns>The resource builder.</ats-returns>
    [AspireExport("withBuildArg")]
    internal static IResourceBuilder<T> WithBuildArgExport<T>(
        this IResourceBuilder<T> builder,
        string name,

View on GitHub (pinned to 25830f84bd)