microsoft/aspire · error · PolyglotCapabilityInvocationException
Could not invoke ' ' because parameter ' ' expects , but…
Error message
Could not invoke '{methodName}'{targetContext} because parameter '{parameterName}' expects {expectedDescription}, but got {actualDescription}. What it means
This error is thrown by ResolveHandleArgument in the remote host's polyglot (ATS) capability layer when an argument that should be a registered handle cannot be converted to the .NET type the capability method expects. Handles are opaque references clients hold to host-side objects (e.g., builders, resources); the host validates the handle's underlying object against the expected parameter type and throws a typed JSON-RPC type-mismatch exception listing the expected and actual descriptions when conversion fails.
Solutions
- Check which parameter the message names and confirm the handle you pass was obtained from a capability call that returns that exact type.
- Re-acquire the handle by re-invoking the creation API instead of reusing a cached handle across host restarts or reconnections.
- If you have a builder handle but the method wants a resource, call the appropriate build/as method first and pass the returned handle.
- Verify your client binding serializes handle references as handles (not raw JSON values) when constructing the args object.
Example fix
// before
var endpoint = await client.InvokeAsync("GetEndpoint", new JsonObject { ["resource"] = builderHandle });
// after
var resourceHandle = await client.InvokeAsync("GetResource", new JsonObject { ["builder"] = builderHandle });
var endpoint = await client.InvokeAsync("GetEndpoint", new JsonObject { ["resource"] = resourceHandle }); Defensive patterns
Strategy: validation
Validate before calling
function isHandleFor(value, expectedHandleName) {
return value !== null && typeof value === 'object' && '$handle' in value && value.$handle?.type === expectedHandleName;
} Type guard
function isValidHandle(value) {
return value !== null && typeof value === 'object' && typeof (value as any).$handle?.id === 'string';
} Try / catch
try {
await client.InvokeAsync(method, args);
} catch (err) {
if (err.code === -32602 && /expects .* but got/.test(err.message)) {
const param = err.data?.parameterName;
handles = await reacquireHandles(); // re-create stale handles
}
throw err;
} Prevention
- Re-acquire handles from creation APIs after any host restart or reconnect instead of caching them.
- Track the return type of each capability call so each handle is only passed to parameters of the matching type.
- Ensure your client binding serializes handle references as handles rather than plain JSON values.
- Log handle identity alongside usage so mismatches point to the wrong variable quickly.
When it happens
Trigger: Calling a remote capability method (via exportApi/polyglot invocation over JSON-RPC) and passing, as a handle-typed parameter: (1) an unregistered or stale handle object, (2) a handle whose underlying object is of a different type than the parameter expects (e.g., passing a resource builder where a resource is required and the builder's Resource property does not match), or (3) a plain JSON value instead of a handle.
Common situations: A client script caches a handle across sessions where the host restarted and the handle registry was reset; a caller passes a builder handle to a method expecting the built resource of an incompatible type; a language binding serializes the handle incorrectly so the raw object arrives without handle identity; passing the wrong handle variable after refactoring client code.
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
- Endpoint must be a string, endpoint reference, or reference…
- Handle ' ' contains , expected
- Partition key paths must be a string or a string collection.
- TYPE_MISMATCH
- URL must be a string, Uri, or parameter resource builder.
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/db1900be7b2e91c2.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.RemoteHost/Ats/PolyglotCapabilityInvocationException.cs:192
innerException);
}
public static object ResolveHandleArgument(
string capabilityId,
string? polyglotMethodName,
JsonObject? args,
HandleRegistry handles,
string parameterName,
Type expectedType,
object handleObject,
string? targetParameterName = null)
{
if (TryConvertHandle(handleObject, expectedType, out var converted))
{
return converted!;
}
throw CreateTypeMismatch(
capabilityId,
polyglotMethodName,
args,
handles,
parameterName,
expectedType,
handleObject,
targetParameterName);
}
private static bool TryConvertHandle(object handleObject, Type expectedType, out object? converted)
{
if (expectedType.IsInstanceOfType(handleObject))
{
converted = handleObject;
return true;
}
View on GitHub (pinned to 25830f84bd)