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

  1. Use a supported package manager (npm, pnpm, yarn, bun) whose metadata includes ProductionInstallArgs.
  2. If you override the install command via WithInstallCommand, supply production install args (e.g. '--omit=dev').
  3. 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

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


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)