microsoft/aspire · error · InvalidOperationException

' ' is missing AppendLiteral(string).

Error message

'{builder.GetType().FullName}' is missing AppendLiteral(string).

What it means

AppendLiteral reflectively locates a public instance AppendLiteral(string) method on the ReferenceExpression.Builder instance. If the method is not found (renamed, non-public, removed, or wrong object passed in), the code throws this InvalidOperationException naming the builder's type.

Solutions

  1. Ensure you pass the un-built ReferenceExpression.Builder object, not a built ReferenceExpression.
  2. Align the Aspire.Hosting package version with the one RemoteHost expects.
  3. If trimming/AOT, preserve Builder.AppendLiteral via [DynamicDependency].
  4. Confirm the string argument is a string (the lookup targets exactly AppendLiteral(string)).

Example fix

// before
var expression = ReferenceExpression.Create(...);
AppendLiteral(expression, "literal"); // wrong object

// after
var builder = CreateReferenceExpressionBuilder();
AppendLiteral(builder, "literal");
Defensive patterns

Strategy: type-guard

Validate before calling

var m = builder.GetType().GetMethod("AppendLiteral", BindingFlags.Instance | BindingFlags.Public, null, [typeof(string)], null);
if (m is null)
    throw new NotSupportedException($"{builder.GetType().FullName} lacks AppendLiteral(string); pass a ReferenceExpression.Builder, not a built expression.");

Type guard

static bool SupportsAppendLiteral(object builder) =>
    builder.GetType().GetMethod("AppendLiteral", BindingFlags.Instance | BindingFlags.Public, null, [typeof(string)], null) is not null;

Try / catch

try
{
    AppendLiteral(builder, value);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("missing AppendLiteral"))
{
    logger.LogError(ex, "Builder surface mismatch on {Type}", builder.GetType().FullName);
}

Prevention

When it happens

Trigger: ToValueReferenceExpression calls AppendLiteral(builder, value) and builder.GetType().GetMethod("AppendLiteral", Public|Instance, types: [typeof(string)]) returns null.

Common situations: Passing a ReferenceExpression (built) instead of the Builder to AppendLiteral; Aspire.Hosting version where Builder.AppendLiteral signature changed; trimming removed the method.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting.RemoteHost/Ats/ReferenceExpressionRef.cs:334

        return [.. parts];
    }

    private static object CreateReferenceExpressionBuilder()
    {
        var builderType = GetRequiredHostingType(HostingTypeNames.ReferenceExpressionBuilder);
        return Activator.CreateInstance(builderType)
            ?? throw new InvalidOperationException($"Failed to create '{builderType.FullName}'.");
    }

    private static void AppendLiteral(object builder, string value)
    {
        var appendLiteralMethod = builder.GetType().GetMethod(
            "AppendLiteral",
            BindingFlags.Instance | BindingFlags.Public,
            binder: null,
            [typeof(string)],
            modifiers: null)
            ?? throw new InvalidOperationException($"'{builder.GetType().FullName}' is missing AppendLiteral(string).");

        appendLiteralMethod.Invoke(builder, [value]);
    }

    private static void AppendValueProvider(object builder, object valueProvider)
    {
        var appendValueProviderMethod = builder.GetType().GetMethod(
            "AppendValueProvider",
            BindingFlags.Instance | BindingFlags.Public,
            binder: null,
            [typeof(object), typeof(string)],
            modifiers: null)
            ?? throw new InvalidOperationException($"'{builder.GetType().FullName}' is missing AppendValueProvider(object, string).");

        appendValueProviderMethod.Invoke(builder, [valueProvider, null]);
    }

    private static object BuildReferenceExpression(object builder)

View on GitHub (pinned to 25830f84bd)