microsoft/aspire · error · InvalidOperationException
Package manager ' ' does not have ProductionInstallArgs…
Error message
Package manager '{packageManager.ExecutableName}' does not have ProductionInstallArgs configured, which is required for PublishAsPackageScript. What it means
PublishAsPackageScript builds a container image that reinstalls production-only dependencies in a Dockerfile stage. That stage needs the package manager's ProductionInstallArgs (e.g. '--omit=dev') from JavaScriptInstallCommandAnnotation. The detected package manager does not define them, so Aspire cannot emit a correct production install command and fails instead of publishing an image with dev dependencies.
Solutions
- Use a supported package manager (npm, pnpm, yarn, bun) whose metadata includes ProductionInstallArgs.
- If you override the install command via WithInstallCommand, supply production install args (e.g. '--omit=dev').
- If genuinely unsupported, publish with a custom Dockerfile instead of PublishAsPackageScript.
Example fix
// before
appBuilder.WithInstallCommand("my-pm", "install"); // no production args
appBuilder.PublishAsPackageScript();
// after
appBuilder.WithInstallCommand("my-pm", "install", productionInstallArgs: "--omit=dev");
appBuilder.PublishAsPackageScript(); Defensive patterns
Strategy: validation
Validate before calling
if (string.IsNullOrEmpty(installAnnotation?.ProductionInstallArgs))
throw new InvalidOperationException("Configure ProductionInstallArgs before PublishAsPackageScript."); Try / catch
try { appBuilder.PublishAsPackageScript(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("ProductionInstallArgs"))
{
// fall back to a custom Dockerfile or fix the install annotation
} Prevention
- Stick to supported package managers (npm, pnpm, yarn, bun) for published containers.
- When overriding install commands, always include production install args.
- Review package-manager metadata before using PublishAsPackageScript.
When it happens
Trigger: Calling PublishAsPackageScript on a JavaScript resource whose JavaScriptInstallCommandAnnotation has null/empty ProductionInstallArgs — typically a custom package manager or one overridden via WithInstallCommand without production args.
Common situations: Custom package managers registered without full install metadata; overriding the install command and forgetting the production variant; a package manager newer than Aspire's built-in metadata.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- DockerfileBuildAnnotation should exist after calling…
- JavaScript app resource
- apiPath is required when apiTarget is specified.
- apiTarget is required when apiPath is specified.
- Bun apps cannot be debugged through the Node dev-server…
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/c6541484b52a5155.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.JavaScript/JavaScriptHostingExtensions.cs:1838
if (packageManager.PackageFilesPatterns.Count > 0)
{
foreach (var packageFilePattern in packageManager.PackageFilesPatterns)
{
prodDepsStage.Copy(packageFilePattern.Source, packageFilePattern.Destination);
}
}
else
{
prodDepsStage.Copy("package*.json", "./");
}
// Install production-only dependencies using the same base install
// command as the build stage (e.g. 'ci' for npm, 'install --frozen-lockfile'
// for pnpm) plus the production-only flag (e.g. '--omit=dev').
var installAnnotation = c.Resource.TryGetLastAnnotation<JavaScriptInstallCommandAnnotation>(out var installCmd) ? installCmd : null;
if (string.IsNullOrEmpty(installAnnotation?.ProductionInstallArgs))
{
throw new InvalidOperationException($"Package manager '{packageManager.ExecutableName}' does not have ProductionInstallArgs configured, which is required for PublishAsPackageScript.");
}
var prodInstallCmd = BuildProductionInstallCommand(packageManager, installAnnotation);
if (!string.IsNullOrEmpty(packageManager.CacheMount))
{
prodDepsStage.Run($"--mount=type=cache,target={packageManager.CacheMount} {prodInstallCmd}");
}
else
{
prodDepsStage.Run(prodInstallCmd);
}
// Runtime stage: copy build output then overlay prod deps
var runtimeStage = dockerfileContext.Builder
.From(runtimeImage, "runtime")
.WorkDir("/app")
.CopyFrom("build", "/app", "/app")
.CopyFrom("prod-deps", "/app/node_modules", "./node_modules");View on GitHub (pinned to 25830f84bd)