{"record":{"id":"384624adf5544bd8","repo":"microsoft/aspire","slug":"dockerfilebuildannotation-should-exist-after-calling","errorCode":null,"errorMessage":"DockerfileBuildAnnotation should exist after calling PublishAsDockerFile.","messagePattern":"DockerfileBuildAnnotation should exist after calling PublishAsDockerFile\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.JavaScript/JavaScriptHostingExtensions.cs","lineNumber":1896,"sourceCode":"                                    .CopyFrom(\"build\", \"/app/.next/standalone\", \"./\", \"node:node\")\n                                    .CopyFrom(\"build\", \"/app/.next/static\", \"./.next/static\", \"node:node\")\n                                    .User(\"node\")\n                                    .Entrypoint([\"node\", \"server.js\"]);\n                                break;\n                            }\n                        }\n                    }\n                });\n\n                // JavaScript apps default to build-only publishing unless a standalone runtime is enabled.\n                if (resource.TryGetLastAnnotation<DockerfileBuildAnnotation>(out var dockerFileAnnotation))\n                {\n                    dockerFileAnnotation.HasEntrypoint =\n                        resource.TryGetLastAnnotation<JavaScriptPublishModeAnnotation>(out _);\n                }\n                else\n                {\n                    throw new InvalidOperationException(\"DockerfileBuildAnnotation should exist after calling PublishAsDockerFile.\");\n                }\n            })\n            .WithAnnotation(new ContainerFilesSourceAnnotation() { SourcePath = \"/app/dist\" })\n            .WithBuildScript(\"build\")\n            .WithRunScript(runScriptName);\n\n        if (builder.ExecutionContext.IsPublishMode &&\n            builder.TryCreateResourceBuilder<ContainerResource>(resource.Name, out var containerBuilder))\n        {\n            var validationStepName = $\"validate-javascript-dockerfile-run-script-{resource.Name}\";\n\n            Task WriteValidatedContainerAsync(ManifestPublishingContext context)\n            {\n                ValidateExistingDockerfileRunScript(resource, containerBuilder.Resource);\n                return context.WriteContainerAsync(containerBuilder.Resource);\n            }\n\n            resourceBuilder.WithManifestPublishingCallback(WriteValidatedContainerAsync);","sourceCodeStart":1878,"sourceCodeEnd":1914,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.JavaScript/JavaScriptHostingExtensions.cs#L1878-L1914","documentation":"Internal invariant check inside the publish-configuration callback: after the callback runs, the code expects DockerfileBuildAnnotation (added by PublishAsDockerFile) to exist, but it was not found. Hitting this means the resource publish pipeline did not follow the API contract the extension assumes.","triggerScenarios":"Running this publish callback on a resource where PublishAsDockerFile was not invoked (or its annotation was removed), so TryGetAnnotation<DockerfileBuildAnnotation> fails.","commonSituations":"Custom publish pipelines bypassing PublishAsDockerFile; manually stripping annotations in an AppHost; calling the API out of order on an unsupported resource type.","solutions":["Ensure PublishAsDockerFile(...) is called on the resource builder so the DockerfileBuildAnnotation is created.","If managing the Dockerfile annotation manually, use the public PublishAsDockerFile API instead.","Check whether a custom event subscriber removes DockerfileBuildAnnotation before publish callbacks run."],"exampleFix":"// before\nvar app = builder.AddViteApp(\"frontend\", \"./frontend\");\napp.WithRunScript(\"build:prod\"); // annotation missing\n// after\nvar app = builder.AddViteApp(\"frontend\", \"./frontend\")\n    .PublishAsDockerFile();\napp.WithRunScript(\"build:prod\");","handlingStrategy":"try-catch","validationCode":"if (!resource.TryGetLastAnnotation<DockerfileBuildAnnotation>(out _))\n    resource = resource.PublishAsDockerFile();","typeGuard":"bool HasDockerfileBuildAnnotation(IResource r) => r.TryGetLastAnnotation<DockerfileBuildAnnotation>(out _);","tryCatchPattern":"try { ConfigurePublish(builder); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"DockerfileBuildAnnotation\"))\n{\n    builder.PublishAsDockerFile(); // then retry configuration\n}","preventionTips":["Always call PublishAsDockerFile before configuring publish-mode callbacks.","Do not remove annotations from resources manually.","Keep publish configuration in one place so ordering is obvious."],"tags":["aspire","javascript","internal-invariant","dockerfile","publish"],"backgroundTag":"internal-invariant-violation","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}