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
- 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.
- 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.
- For custom types, implement both IValueProvider (async GetValueAsync) and IManifestExpressionProvider (ManifestExpression) on the class.
- 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
- Only pass resources, parameters, or ReferenceExpressions that document support for expression generation.
- For custom providers, always implement both IValueProvider and IManifestExpressionProvider together.
- Check the resource type's implemented interfaces when switching Aspire versions.
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
- Object must implement IManifestExpressionProvider
- At least one process command success exit code must be…
- Launch arguments must contain at least one entry.
- ReferenceExpression instances can't be used in interpolated…
- The executable path cannot be null, empty, or whitespace.
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)