microsoft/aspire · error · ArgumentOutOfRangeException
The permission kind must be a defined DenoPermissionKind…
Error message
The permission kind must be a defined DenoPermissionKind value.
What it means
AddDenoPermission validates that the DenoPermissionKind argument is a defined enum member before building the --allow/--deny flag. An undefined value (bad cast, new member from a newer assembly) would otherwise emit a malformed Deno CLI flag, so it throws ArgumentOutOfRangeException.
Solutions
- Use the named DenoPermissionKind constants (e.g. DenoPermissionKind.Read) instead of casts.
- Validate with Enum.IsDefined before converting config input to the enum.
- Rebuild against the same Aspire.Hosting.JavaScript version you run with.
- If adding a new DenoPermissionKind member, the library (not user code) must be updated.
Example fix
// before
var kind = (DenoPermissionKind)Enum.Parse(typeof(DenoPermissionKind), configValue, ignoreCase: true);
resource.WithDenoAllow(kind);
// after
if (!Enum.TryParse<DenoPermissionKind>(configValue, ignoreCase: true, out var kind) || !Enum.IsDefined(kind))
throw new ArgumentException($"Unknown Deno permission kind '{configValue}'.");
resource.WithDenoAllow(kind); Defensive patterns
Strategy: validation
Validate before calling
if (!Enum.IsDefined(typeof(DenoPermissionKind), kind)) throw new ArgumentException("kind must be a defined DenoPermissionKind"); Type guard
static bool IsDefinedPermission(DenoPermissionKind k) => Enum.IsDefined(k);
Try / catch
try { resource.WithDenoAllow(kind, values); } catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "kind") { /* surface as config error */ } Prevention
- Prefer Enum.TryParse + Enum.IsDefined over direct casts
- Use constants, not magic numbers, for enum arguments
- Pin Aspire package versions so enum definitions match
When it happens
Trigger: Calling WithDenoAllow/WithDenoDeny with a kind value obtained by casting an int/string that is not a defined DenoPermissionKind, or from a mismatched assembly version with different enum values.
Common situations: Parsing permission kinds from JSON/YAML config and casting directly; binary incompatibility after enum changes; hand-rolled helper methods constructing the enum.
Understand the failure class
Background: "invalid argument", "unknown mode", "not supported": invalid enum-like argument errors explained — this error's family across 19 libraries.
Related errors
- The node_modules mode must be a defined…
- Deno permission values cannot be null or empty.
- The inspect mode must be a defined DenoInspectMode value.
- ArgumentOutOfRangeException: Specified argument was out of…
- ' ' is not a valid Azure sandbox tier.
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/5cf264fcd982f2b8.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.JavaScript/DenoHostingExtensions.cs:48
if (!builder.Resource.TryGetLastAnnotation<DenoCommandLineAnnotation>(out var annotation))
{
annotation = new DenoCommandLineAnnotation();
builder.WithAnnotation(annotation);
}
return annotation;
}
private static IResourceBuilder<DenoAppResource> AddDenoPermission(
IResourceBuilder<DenoAppResource> builder,
DenoPermissionKind kind,
bool deny,
string[] values)
{
ArgumentNullException.ThrowIfNull(builder);
if (!Enum.IsDefined(kind))
{
throw new ArgumentOutOfRangeException(nameof(kind), kind, "The permission kind must be a defined DenoPermissionKind value.");
}
// The caller owns the params array and can keep mutating it after this call. Permissions are only read
// when the command line is materialized (publish, or resource start), so holding the caller's array by
// reference would let a later mutation silently rewrite the launch arguments. Snapshot it, matching the
// copy semantics WithDenoScriptArgs and WithDenoRuntimeArgs already get from AddRange.
string[] snapshot = values is null ? [] : [.. values];
var permission = new DenoPermission
{
Kind = kind,
Deny = deny,
Values = snapshot,
};
// Deno delimits permission values with commas and offers no escape syntax, so a single value containing a
// comma silently becomes several permissions. Verified on Deno 2.9.0: `--allow-read=data,secret` intended as
// one directory named "data,secret" instead grants `data` and `secret` separately, so the requested path is
// denied while unrelated paths are granted. Reject it here rather than emit a command line that meansView on GitHub (pinned to 25830f84bd)