microsoft/aspire · error · NotSupportedException

Unsupported value type

Error message

Unsupported value type {val.GetType()}

What it means

ResolveValue converts a processed value object into a BicepValue<string> for the generated WebSite resource. The switch handles BicepValue<string>, string, ProvisioningParameter, and FormattableString; any other type falls through to this NotSupportedException, which reports the offending type via val.GetType().

Solutions

  1. Convert the value before calling: numbers/bools to string (value.ToString(CultureInfo.InvariantCulture)).
  2. Wrap an interpolated value as a FormattableString (e.g. $"{other}") so BicepFunction.Interpolate handles it.
  3. If it's a BicepValue of another element type, convert it to BicepValue<string> first.
  4. If you're extending the library, add a case for the reported type in the ResolveValue switch.

Example fix

// before
ResolveValue(targetPort); // int
// after
ResolveValue(targetPort.ToString(CultureInfo.InvariantCulture));
Defensive patterns

Strategy: type-guard

Validate before calling

static bool IsResolvableBicepInput(object v) =>
    v is BicepValue<string> or string or ProvisioningParameter or FormattableString;

Type guard

if (val is not (BicepValue<string> or string or ProvisioningParameter or FormattableString))
    val = val switch { IFormattable f => f.ToString(null, CultureInfo.InvariantCulture), _ => val.ToString() };

Try / catch

try { bicepValue = ResolveValue(val); }
catch (NotSupportedException ex) when (ex.Message.StartsWith("Unsupported value type"))
{
    bicepValue = ResolveValue(val.ToString() ?? string.Empty);
}

Prevention

When it happens

Trigger: ResolveValue is invoked (from 'conditional'/'value' helpers while building the WebSite) with a value that is none of BicepValue<string>, string, ProvisioningParameter, or FormattableString — e.g. an int, bool, or BicepValue<int> passed straight through without conversion.

Common situations: Passing non-string primitives (port numbers, flags) directly as website property values; custom website customization annotations feeding typed BicepValue<int>/bool into paths that expect string-typed values; internal refactors that changed the set of value types flowing into ResolveValue.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting.Azure.AppService/AzureAppServiceWebsiteContext.cs:320

        }

        if (value is IManifestExpressionProvider manifestExpressionProvider)
        {
            return (AllocateParameter(manifestExpressionProvider, secretType), secretType);
        }

        throw new NotSupportedException($"Unsupported value type {value.GetType()}");
    }

    private static BicepValue<string> ResolveValue(object val)
    {
        return val switch
        {
            BicepValue<string> s => s,
            string s => s,
            ProvisioningParameter p => p,
            FormattableString fs => BicepFunction.Interpolate(fs),
            _ => throw new NotSupportedException($"Unsupported value type {val.GetType()}")
        };
    }

    public void BuildWebSite(AzureResourceInfrastructure infra)
    {
        _infrastructure = infra;

        // Check for deployment slot
        // If specified, update hostnames to endpoint references
        BicepValue<string>? deploymentSlotValue = null;
        if (environmentContext.Environment.DeploymentSlotParameter is not null || environmentContext.Environment.DeploymentSlot is not null)
        {
            deploymentSlotValue = environmentContext.Environment.DeploymentSlotParameter != null
                ? environmentContext.Environment.DeploymentSlotParameter.AsProvisioningParameter(infra)
                : environmentContext.Environment.DeploymentSlot!;

            UpdateHostNameForSlot(deploymentSlotValue);
        }

View on GitHub (pinned to 25830f84bd)