{"record":{"id":"23615e1fbf25d0ff","repo":"microsoft/aspire","slug":"the-resource-builder-resource-name-does-not-have-a-container","errorCode":null,"errorMessage":"The resource '{builder.Resource.Name}' does not have a container image specified. Use WithImage to specify the container image and tag.","messagePattern":"The resource '(.+?)' does not have a container image specified\\. Use WithImage to specify the container image and tag\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting/ContainerResourceBuilderExtensions.cs","lineNumber":620,"sourceCode":"\n    /// <summary>\n    /// Sets the pull policy for the container resource.\n    /// </summary>\n    /// <typeparam name=\"T\">The resource type.</typeparam>\n    /// <param name=\"builder\">Builder for the container resource.</param>\n    /// <param name=\"pullPolicy\">The pull policy behavior for the container resource.</param>\n    /// <returns>The <see cref=\"IResourceBuilder{T}\"/>.</returns>\n    /// <ats-returns>The resource builder.</ats-returns>\n    [AspireExport]\n    public static IResourceBuilder<T> WithImagePullPolicy<T>(this IResourceBuilder<T> builder, ImagePullPolicy pullPolicy) where T : ContainerResource\n    {\n        ArgumentNullException.ThrowIfNull(builder);\n\n        return builder.WithAnnotation(new ContainerImagePullPolicyAnnotation { ImagePullPolicy = pullPolicy }, ResourceAnnotationMutationBehavior.Replace);\n    }\n    private static IResourceBuilder<T> ThrowResourceIsNotContainer<T>(IResourceBuilder<T> builder) where T : ContainerResource\n    {\n        throw new InvalidOperationException($\"The resource '{builder.Resource.Name}' does not have a container image specified. Use WithImage to specify the container image and tag.\");\n    }\n\n    /// <summary>\n    /// Changes the resource to be published as a container in the manifest.\n    /// </summary>\n    /// <param name=\"builder\">Resource builder.</param>\n    /// <returns>The <see cref=\"IResourceBuilder{T}\"/>.</returns>\n    /// <ats-returns>The resource builder.</ats-returns>\n    [AspireExport]\n    public static IResourceBuilder<T> PublishAsContainer<T>(this IResourceBuilder<T> builder) where T : ContainerResource\n    {\n        ArgumentNullException.ThrowIfNull(builder);\n\n        return builder.WithManifestPublishingCallback(context => context.WriteContainerAsync(builder.Resource));\n    }\n\n    /// <summary>\n    /// Causes Aspire to build the specified container image from a Dockerfile.","sourceCodeStart":602,"sourceCodeEnd":638,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting/ContainerResourceBuilderExtensions.cs#L602-L638","documentation":"Image-related APIs (WithImageTag, WithImageRegistry, WithImageSHA256) require the resource to already have a container image annotation, which is normally set by WithImage. When the annotation is missing, ThrowResourceIsNotContainer throws this InvalidOperationException because there is no image to tag, register, or digest-pin.","triggerScenarios":"Calling WithImageTag/WithImageRegistry/WithImageSHA256 on a container resource builder that never had WithImage called (or on a resource created without an image).","commonSituations":"Refactoring that removed or reordered WithImage; building containers from Dockerfiles (WithDockerfile) and then calling image-mutating APIs; copy-pasted builder chains missing the WithImage step.","solutions":["Call WithImage(\"<image>\") before WithImageTag/WithImageRegistry/WithImageSHA256 in the builder chain.","If the container is built from a Dockerfile, use WithDockerfile-related APIs instead of image annotation APIs.","Reorder the fluent chain so WithImage appears first.","exampleFix placeholder"],"exampleFix":"// before\nbuilder.AddContainer(\"app\", \"image\").WithImageTag(\"1.0\"); // no image set\n// after\nbuilder.AddContainer(\"app\", \"image\").WithImage(\"myrepo/myapp\").WithImageTag(\"1.0\");","handlingStrategy":"validation","validationCode":"bool HasImage<T>(IResourceBuilder<T> builder) where T : ContainerResource =>\n    builder.Resource.Annotations.OfType<ContainerImageAnnotation>().Any();\nif (!HasImage(builder)) throw new InvalidOperationException(\"Call WithImage before WithImageTag/WithImageRegistry/WithImageSHA256.\");","typeGuard":"bool HasImage<T>(IResourceBuilder<T> b) where T : ContainerResource =>\n    b.Resource.Annotations.OfType<ContainerImageAnnotation>().Any();","tryCatchPattern":"try\n{\n    resource.WithImageTag(\"1.0\");\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"does not have a container image\"))\n{\n    // Add WithImage first and retry\n}","preventionTips":["Always start container resource chains with WithImage (or WithDockerfile).","In shared builder helpers, assert the image annotation exists before mutating image settings.","When refactoring fluent chains, keep WithImage as the first image-related call."],"tags":["container-image","builder","aspire"],"backgroundTag":"invalid-state-transition","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T09:17:21.228Z"}