microsoft/aspire · error · InvalidOperationException
No client connection available for callback invocation
Error message
No client connection available for callback invocation
What it means
JsonRpcCallbackInvoker lets server-side code call back into the connected client by callbackId. This InvalidOperationException is thrown when InvokeAsync is called but no client JsonRpc connection has been attached to the invoker yet (or it was detached), so there is no transport to send the 'invokeCallback' request on.
Solutions
- Ensure the client JsonRpc instance is attached to the callback invoker before any code path can trigger callbacks.
- Guard callback invocations behind client-connected state or defer them until the connection is established.
- Treat client disconnect as terminal for pending callbacks: cancel or drop them instead of invoking.
- If a callback is optional, check availability (e.g. a TryInvoke or null clientRpc) and skip gracefully.
Example fix
// before
await callbackInvoker.InvokeAsync<object?>("refreshResources", args);
// after
if (callbackInvoker.HasClientConnection)
{
await callbackInvoker.InvokeAsync<object?>("refreshResources", args);
} Defensive patterns
Strategy: type-guard
Validate before calling
// Check the invoker is connected before invoking: if (invoker.ClientRpc is null) return; // or queue the callback
Type guard
bool CanInvoke(JsonRpcCallbackInvoker invoker) => invoker.HasClientConnection;
Try / catch
try { await invoker.InvokeAsync<object?>(callbackId, args); }
catch (InvalidOperationException ex) when (ex.Message.Contains("No client connection"))
{ /* drop or defer callback */ } Prevention
- Attach the client JsonRpc to the invoker during startup, before enabling any feature that fires callbacks.
- Cancel in-flight callback work when the client disconnects.
- Make callbacks best-effort with explicit availability checks.
When it happens
Trigger: Server-side code invoking a registered callback (via InvokeAsync of the callback invoker) before a client connection is assigned to _clientRpc, or after the client connection was cleared/disposed.
Common situations: Callback fired during startup before the dashboard/client finished connecting; a background task outliving the client session and attempting a callback after disconnect; wiring the invoker without registering the client RPC instance.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Callback ' ' timed out after s
- Callback not found
- -32602
- A ConfigureRadiusInfrastructure callback changed the value…
- A discovered Toolbox tool did not have a name.
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/e1c9604402d9336d.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.RemoteHost/JsonRpcCallbackInvoker.cs:35
/// <summary>
/// Sets the JSON-RPC connection to use for invoking callbacks.
/// </summary>
/// <param name="clientRpc">The JSON-RPC connection.</param>
public void SetConnection(JsonRpc clientRpc)
{
_clientRpc = clientRpc;
}
/// <inheritdoc />
public bool IsConnected => _clientRpc != null;
/// <inheritdoc />
public async Task<TResult> InvokeAsync<TResult>(string callbackId, JsonNode? args, CancellationToken cancellationToken = default)
{
if (_clientRpc == null)
{
throw new InvalidOperationException("No client connection available for callback invocation");
}
using var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
cts.CancelAfter(s_callbackTimeout);
try
{
return await _clientRpc.InvokeWithCancellationAsync<TResult>(
"invokeCallback",
[callbackId, args],
cts.Token).ConfigureAwait(false);
}
catch (OperationCanceledException) when (!cancellationToken.IsCancellationRequested)
{
throw new TimeoutException($"Callback '{callbackId}' timed out after {s_callbackTimeout.TotalSeconds}s");
}
}
View on GitHub (pinned to 25830f84bd)