microsoft/aspire · error · ArgumentException

Expected a literal or .

Error message

Expected a {typeof(T).Name} literal or {nameof(BicepValueProxy)}.

What it means

BicepValueProxy.Convert<T> unwraps a stored value to a concrete literal of type T. If the underlying value is not an instance of T (nor convertible via the checked path), the method throws ArgumentException stating it expected a T literal or a BicepValueProxy. This guards callers against silently mistyping Bicep values.

Solutions

  1. Call Convert with the generic type matching the literal originally stored (check the producing code).
  2. Parse/convert explicitly first: int.TryParse on strings before Convert<int>, or ToString() before Convert<string>.
  3. Use nullable-aware checks on the proxy's value type before converting.
  4. Centralize the expected type in one place so producer and consumer agree.

Example fix

// before
var port = proxy.Convert<int>(); // stored as string "8080"

// after
var port = int.Parse(proxy.Convert<string>());
Defensive patterns

Strategy: type-guard

Validate before calling

if (proxy.ValueType == typeof(int)) { /* safe: proxy.Convert<int>() */ }

Type guard

bool CanConvert<T>(BicepValueProxy p) where T : notnull => p.ValueType == typeof(T) || Nullable.GetUnderlyingType(p.ValueType) == typeof(T);

Try / catch

try { var v = proxy.Convert<int>(); }
catch (ArgumentException ex) when (ex.Message.Contains("literal or BicepValueProxy")) { /* read with the stored type and convert manually */ }

Prevention

When it happens

Trigger: Calling Convert<T> (e.g. Convert<int>, Convert<string>) on a BicepValueProxy whose stored value was created from a different literal type — such as converting a string '8080' proxy to int, or an int proxy to string.

Common situations: Reading back a Bicep value with a mismatched generic argument; refactoring a value from string to int (or vice versa) in one place but not the read site; passing values parsed from config as strings into Convert<int>.

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/ecd6718f06257359. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting.Azure.Provisioning/BicepValueProxy.cs:143

    public static BicepValue<T> Convert<T>(object value)
    {
        ArgumentNullException.ThrowIfNull(value);

        if (value is BicepValueProxy proxy)
        {
            proxy.EnsureLiteralType<T>();

            var converted = new BicepValue<T>((T)default!);
            proxy.AssignTo(converted);
            return converted;
        }

        if (value is T literal)
        {
            return literal;
        }

        throw new ArgumentException($"Expected a {typeof(T).Name} literal or {nameof(BicepValueProxy)}.", nameof(value));
    }

    internal static BicepValueProxy CreateExpression(BicepExpression expression, bool isSecure)
    {
        ArgumentNullException.ThrowIfNull(expression);

        return new(new BicepValue<object>(expression), typeof(object), isSecure);
    }

    internal BicepExpression ToBicepExpression()
    {
        return _value.ToBicepExpression();
    }

    internal BicepValue<object> ToObjectBicepValue()
    {
        return new(ToBicepExpression());
    }

View on GitHub (pinned to 25830f84bd)