microsoft/aspire · error · InvalidOperationException

The resource ' ' does not have a Dockerfile build…

Error message

The resource '{builder.Resource.Name}' does not have a Dockerfile build annotation. Call WithDockerfile before calling WithBuildArg.

What it means

WithBuildArg adds a build argument to a resource's Dockerfile build annotation. If the resource has no DockerfileBuildAnnotation — i.e. WithDockerfile was never called — the library throws this InvalidOperationException telling you to configure the Dockerfile build first.

Solutions

  1. Call WithDockerfile("<contextPath>") (optionally with a Dockerfile name) before WithBuildArg.
  2. Remove WithBuildArg calls for resources that run a prebuilt image — build args only apply to builds.
  3. For secrets during build, use WithBuildSecret instead of WithBuildArg after adding WithDockerfile.
  4. exampleFix placeholder

Example fix

// before
builder.AddContainer("app", "image")
    .WithBuildArg("CONFIG", value);
// after
builder.AddContainer("app", "image")
    .WithDockerfile("./MyApp")
    .WithBuildArg("CONFIG", value);
Defensive patterns

Strategy: validation

Validate before calling

bool HasDockerfile<T>(IResourceBuilder<T> builder) where T : ContainerResource =>
    builder.Resource.Annotations.OfType<DockerfileBuildAnnotation>().Any();
if (!HasDockerfile(builder)) throw new InvalidOperationException("Call WithDockerfile before WithBuildArg.");

Type guard

bool HasDockerfile<T>(IResourceBuilder<T> b) where T : ContainerResource =>
    b.Resource.Annotations.OfType<DockerfileBuildAnnotation>().Any();

Try / catch

try
{
    resource.WithBuildArg("CONFIG", value);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("Dockerfile build annotation"))
{
    // Call WithDockerfile first and retry
}

Prevention

When it happens

Trigger: Calling WithBuildArg (or WithBuildArg<T>) on a container resource that was created with WithImage only, or without WithDockerfile.

Common situations: Adding build args to a pre-built image resource; copy-pasting builder configuration between Dockerfile-built and image-pull resources; ordering mistakes in shared builder helpers.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

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

    ///        .WithDockerfile("../mycontainer")
    ///        .WithBuildArg("CUSTOM_BRANDING", "/app/static/branding/custom");
    ///
    /// builder.Build().Run();
    /// </code>
    /// </example>
    /// </remarks>
    /// <remarks>This method is not available in polyglot app hosts. Use the ATS dispatcher overload instead.</remarks>
    [AspireExportIgnore(Reason = "Uses object parameter which is not ATS-compatible.")]
    public static IResourceBuilder<T> WithBuildArg<T>(this IResourceBuilder<T> builder, string name, object? value) where T : ContainerResource
    {
        ArgumentNullException.ThrowIfNull(builder);
        ArgumentException.ThrowIfNullOrEmpty(name);

        var annotation = builder.Resource.Annotations.OfType<DockerfileBuildAnnotation>().SingleOrDefault();

        if (annotation is null)
        {
            throw new InvalidOperationException($"The resource '{builder.Resource.Name}' does not have a Dockerfile build annotation. Call WithDockerfile before calling WithBuildArg.");
        }

        annotation.BuildArguments[name] = value;

        return builder;
    }

    /// <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 resource builder for a parameter resource.</param>
    /// <returns>The <see cref="IResourceBuilder{T}"/>.</returns>
    /// <exception cref="InvalidOperationException">
    /// Thrown when <see cref="ContainerResourceBuilderExtensions.WithBuildArg{T}(IResourceBuilder{T}, string, IResourceBuilder{ParameterResource})"/> is
    /// called before <see cref="ContainerResourceBuilderExtensions.WithDockerfile{T}(IResourceBuilder{T}, string, string?, string?)"/>.

View on GitHub (pinned to 25830f84bd)