microsoft/aspire · error · InvalidOperationException

Unsupported Deno node_modules mode

Error message

Unsupported Deno node_modules mode '{mode}'.

What it means

GetDenoNodeModulesDirModeValue converts a DenoNodeModulesDirMode into the Deno CLI value ('none'/'auto'/'manual') when building args. Hitting the discard arm with InvalidOperationException is an internal invariant violation: the API-time validation (error 1014) should have rejected any undefined mode, so this signals a new enum member whose mapping was not added, or a value injected via a mismatched assembly.

Solutions

  1. Upgrade all Aspire.* packages to the same version and rebuild.
  2. Do not set NodeModulesDirMode on the annotation directly; use WithDenoNodeModulesDir.
  3. If you added a new DenoNodeModulesDirMode member, add its mapping to GetDenoNodeModulesDirModeValue and file/fix the library bug.
  4. Clear stale build artifacts (bin/obj) and restore to eliminate mixed-version binaries.

Example fix

// before
deno.NodeModulesDirMode = (DenoNodeModulesDirMode)9;
// after
builder.WithDenoNodeModulesDir(DenoNodeModulesDirMode.Manual);
Defensive patterns

Strategy: validation

Validate before calling

if (mode is not null && !Enum.IsDefined(mode.Value)) throw new ArgumentException("Unsupported DenoNodeModulesDirMode before launch.");

Try / catch

try { app.Run(); } catch (InvalidOperationException ex) when (ex.Message.Contains("Unsupported Deno node_modules mode")) { /* report version/config bug */ }

Prevention

When it happens

Trigger: A newly added DenoNodeModulesDirMode member not mapped in GetDenoNodeModulesDirModeValue; mixed-version assemblies where the enum and the mapping differ; bypassing WithDenoNodeModulesDir and setting annotation.NodeModulesDirMode directly.

Common situations: Running an upgraded Aspire.Hosting.JavaScript against cached older binaries (or vice versa); custom code writing to the Deno annotation directly.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting.JavaScript/DenoHostingExtensions.cs:701

        {
            yield return "--lock";
            yield return deno.Lock;
        }

        if (deno.NodeModulesDirSet)
        {
            yield return deno.NodeModulesDirMode is not { } mode
                ? "--node-modules-dir"
                : $"--node-modules-dir={GetDenoNodeModulesDirModeValue(mode)}";
        }
    }

    private static string GetDenoNodeModulesDirModeValue(DenoNodeModulesDirMode mode) => mode switch
    {
        DenoNodeModulesDirMode.None => "none",
        DenoNodeModulesDirMode.Auto => "auto",
        DenoNodeModulesDirMode.Manual => "manual",
        _ => throw new InvalidOperationException($"Unsupported Deno node_modules mode '{mode}'."),
    };

    private static void AppendUnstableFlags(List<object> args, DenoCommandLineAnnotation deno)
    {
        foreach (var flag in deno.UnstableFlags)
        {
            args.Add(flag);
        }
    }

    /// <summary>
    /// Rejects <see cref="WithDenoRuntimeArgs(IResourceBuilder{DenoAppResource}, string[])"/> entries that
    /// collide with a flag Aspire already emits for this resource.
    /// </summary>
    /// <remarks>
    /// Verified against Deno 2.9.0: single-occurrence options fail with
    /// <c>error: the argument '--config &lt;FILE&gt;' cannot be used multiple times</c>, and mutually exclusive
    /// pairs (<c>--config</c> with <c>--no-config</c>, <c>--no-lock</c> with <c>--lock</c>,

View on GitHub (pinned to 25830f84bd)