microsoft/aspire · error · ArgumentException

Object must implement IValueProvider

Error message

Object must implement IValueProvider

What it means

ReferenceExpression.AppendValueProvider accepts an object that must implement both IValueProvider and IManifestExpressionProvider so its value can be resolved at run time and rendered as a manifest expression at publish time. Before checking either interface, the method unwraps IResourceBuilder<IResource> to the underlying resource via covariance. If after unwrapping the object still does not implement IValueProvider, an ArgumentException naming the 'valueProvider' parameter is thrown immediately.

Solutions

  1. Pass the actual resource or parameter (e.g. the IResourceBuilder<T>.Resource of a PostgresDatabaseResource, a parameter resource, or another ReferenceExpression) rather than an arbitrary object.
  2. If passing an IResourceBuilder, it is accepted only when its Resource implements IValueProvider — check the resource type's interfaces or use a resource that supports expression generation.
  3. For custom types, implement both IValueProvider (async GetValueAsync) and IManifestExpressionProvider (ManifestExpression) on the class.
  4. If you just want a literal value, use CreateLiteral or append the string instead of AppendValueProvider.

Example fix

// before
var expr = ReferenceExpression.Create($"Host={someObject}"); // someObject is a plain POCO

// after
var expr = ReferenceExpression.Create($"Host={builder.Resource}"); // resource implements IValueProvider + IManifestExpressionProvider
Defensive patterns

Strategy: validation

Validate before calling

if (value is not (IValueProvider and IManifestExpressionProvider) && value is not IResourceBuilder<IResource>)
{
    throw new ArgumentException("AppendValueProvider requires an object implementing IValueProvider and IManifestExpressionProvider.", nameof(value));
}

Type guard

static bool CanAppend(object? v) =>
    (v is IResourceBuilder<IResource> rb ? rb.Resource : v) is IValueProvider and IManifestExpressionProvider;

Prevention

When it happens

Trigger: Calling ReferenceExpressionBuilder.AppendValueProvider (or an interpolated-string AppendFormatted overload that routes to it) with an object that implements neither IValueProvider nor IManifestExpressionProvider — e.g. a raw string, a plain POCO, an endpoint or connection-string object that isn't a value provider, or a custom type passed by mistake instead of the resource/parameter itself.

Common situations: Passing a builder (IResourceBuilder<T>) whose underlying resource class doesn't implement IValueProvider; passing strings or primitives where a parameter resource or ReferenceExpression is expected; hand-rolling a custom value provider but forgetting IValueProvider while only implementing IManifestExpressionProvider; upgrading Aspire versions where a type stopped implementing IValueProvider.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting/ApplicationModel/ReferenceExpression.cs:600

    /// <summary>
    /// Appends a value provider to the expression using late binding.
    /// The object must implement both <see cref="IValueProvider"/> and <see cref="IManifestExpressionProvider"/>,
    /// or be an <see cref="IResourceBuilder{T}"/> where T implements both interfaces.
    /// </summary>
    /// <ats-summary>Appends a value provider to the reference expression</ats-summary>
    /// <param name="valueProvider">An object that implements both interfaces, or an IResourceBuilder wrapping such an object.</param>
    /// <ats-param name="valueProvider">The value provider to append.</ats-param>
    /// <param name="format">Optional format specifier.</param>
    /// <exception cref="ArgumentException">Thrown if the object doesn't implement the required interfaces.</exception>
    [AspireExport]
    public void AppendValueProvider(object valueProvider, string? format = null)
    {
        // Unwrap IResourceBuilder<T> to get the underlying resource (covariant interface)
        var unwrapped = valueProvider is IResourceBuilder<IResource> rb ? rb.Resource : valueProvider;

        if (unwrapped is not IValueProvider vp)
        {
            throw new ArgumentException($"Object must implement IValueProvider", nameof(valueProvider));
        }
        if (unwrapped is not IManifestExpressionProvider mep)
        {
            throw new ArgumentException($"Object must implement IManifestExpressionProvider", nameof(valueProvider));
        }

        var index = _valueProviders.Count;
        _builder.Append(CultureInfo.InvariantCulture, $"{{{index}}}");

        _valueProviders.Add(vp);
        _manifestExpressions.Add(mep.ValueExpression);
        _stringFormats.Add(format);
    }

    /// <summary>
    /// Builds the <see cref="ReferenceExpression"/>.
    /// </summary>
    /// <ats-summary>Builds the reference expression</ats-summary>

View on GitHub (pinned to 25830f84bd)