microsoft/aspire · error · ArgumentOutOfRangeException

The node_modules mode must be a defined…

Error message

The node_modules mode must be a defined DenoNodeModulesDirMode value.

What it means

WithDenoNodeModulesDir validates the optional DenoNodeModulesDirMode before recording it on the annotation. Passing a value that is not a defined enum member (bad cast or version mismatch) would produce an unsupported 'node-modules-dir' value later, so the library throws ArgumentOutOfRangeException immediately.

Solutions

  1. Pass DenoNodeModulesDirMode.None/Auto/Manual, or call WithDenoNodeModulesDir() with no argument to use the default.
  2. Validate with Enum.IsDefined before casting config input.
  3. Rebuild against matching Aspire package versions.
  4. Update the switch/serialization map in the library when adding new enum members.

Example fix

// before
var mode = (DenoNodeModulesDirMode)int.Parse(config["mode"]);
resource.WithDenoNodeModulesDir(mode);
// after
if (!Enum.TryParse<DenoNodeModulesDirMode>(config["mode"], out var mode) || !Enum.IsDefined(mode))
    throw new ArgumentException($"Unknown node_modules mode '{config["mode"]}'.");
resource.WithDenoNodeModulesDir(mode);
Defensive patterns

Strategy: validation

Validate before calling

if (mode is not null && !Enum.IsDefined(mode.Value)) throw new ArgumentException("mode must be a defined DenoNodeModulesDirMode");

Type guard

static bool IsValidNodeModulesMode(DenoNodeModulesDirMode? m) => m is null || Enum.IsDefined(m.Value);

Try / catch

try { resource.WithDenoNodeModulesDir(mode); } catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "mode") { /* map to config error */ }

Prevention

When it happens

Trigger: Calling WithDenoNodeModulesDir with a mode cast from an int/string that is not None/Auto/Manual, or with a value from a mismatched Aspire.Hosting.JavaScript assembly version.

Common situations: Reading a node-modules mode from configuration and casting directly; stale binary referencing enum members added or renumbered elsewhere; helper code generating enum values.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

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

    /// <c>--node-modules-dir=&lt;mode&gt;</c>.
    /// </summary>
    /// <param name="builder">The Deno app resource builder.</param>
    /// <param name="mode">The node_modules mode. When <see langword="null"/>, emits <c>--node-modules-dir</c> without a value.</param>
    /// <returns>A reference to the <see cref="IResourceBuilder{T}"/>.</returns>
    /// <exception cref="ArgumentOutOfRangeException">Thrown when <paramref name="mode"/> is not a defined <see cref="DenoNodeModulesDirMode"/> value.</exception>
    /// <ats-returns>The resource builder.</ats-returns>
    /// <remarks>
    /// The generated Deno Dockerfile publisher does not support <c>manual</c> mode because it excludes local
    /// <c>node_modules</c> from the build context. Use <c>auto</c> or provide a custom Dockerfile for that mode.
    /// </remarks>
    [AspireExport]
    [Experimental("ASPIREDENO001", UrlFormat = "https://aka.ms/aspire/diagnostics/{0}")]
    public static IResourceBuilder<DenoAppResource> WithDenoNodeModulesDir(this IResourceBuilder<DenoAppResource> builder, DenoNodeModulesDirMode? mode = null)
    {
        ArgumentNullException.ThrowIfNull(builder);
        if (mode is not null && !Enum.IsDefined(mode.Value))
        {
            throw new ArgumentOutOfRangeException(nameof(mode), mode, "The node_modules mode must be a defined DenoNodeModulesDirMode value.");
        }

        var annotation = GetOrAddDenoAnnotation(builder);
        annotation.NodeModulesDirSet = true;
        annotation.NodeModulesDirMode = mode;
        return builder;
    }

    // ---- Unstable flags ---------------------------------------------------------------------

    /// <summary>
    /// Adds one or more <c>--unstable-*</c> flags. Each feature may be supplied bare (for example <c>"kv"</c>,
    /// <c>"worker-options"</c>, <c>"sloppy-imports"</c>) or fully qualified (<c>"--unstable-kv"</c>).
    /// </summary>
    /// <param name="builder">The Deno app resource builder.</param>
    /// <param name="features">The unstable feature names or fully-qualified <c>--unstable-*</c> flags to emit.</param>
    /// <returns>A reference to the <see cref="IResourceBuilder{T}"/>.</returns>
    /// <ats-returns>The resource builder.</ats-returns>

View on GitHub (pinned to 25830f84bd)