microsoft/aspire · error · TimeoutException

Callback ' ' timed out after s

Error message

Callback '{callbackId}' timed out after {s_callbackTimeout.TotalSeconds}s

What it means

When invoking a client callback, JsonRpcCallbackInvoker wraps the call in a linked CancellationTokenSource with a fixed timeout (s_callbackTimeout). If the client does not respond before that timeout (and the caller's own token was not cancelled), the OperationCanceledException is converted into this TimeoutException naming the callback id and timeout in seconds.

Solutions

  1. Verify the client actually implements and responds to the given callbackId and return promptly.
  2. Check the client for blocking work (sync-over-async, locks, debugger pauses) on its RPC handler thread.
  3. Increase responsiveness or move long work off the callback path; acknowledge quickly then process async if the protocol allows.
  4. Catch TimeoutException on the caller side and degrade gracefully or retry if the callback is best-effort.

Example fix

// before
var result = await callbackInvoker.InvokeAsync<bool>("confirmDeploy", args); // hangs then times out

// after
try
{
    var result = await callbackInvoker.InvokeAsync<bool>("confirmDeploy", args);
}
catch (TimeoutException)
{
    // fall back to default behavior when the client is unresponsive
    var result = false;
}
Defensive patterns

Strategy: try-catch

Try / catch

try { await invoker.InvokeAsync<TResult>(callbackId, args, ct); }
catch (TimeoutException) { /* fallback/default behavior or retry */ }

Prevention

When it happens

Trigger: Calling callbackInvoker.InvokeAsync<TResult>(callbackId, args) where the connected client never replies to the 'invokeCallback' request within s_callbackTimeout seconds, or is blocked/slow handling it.

Common situations: Client stuck processing a long-running UI operation; client event loop blocked by a synchronous wait; client hung or paused (debugger breakpoint); network/pipe congestion delaying the response; client not handling that callbackId at all.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting.RemoteHost/JsonRpcCallbackInvoker.cs:50

    {
        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");
        }
    }

    /// <inheritdoc />
    public async Task InvokeAsync(string callbackId, JsonNode? args, CancellationToken cancellationToken = default)
    {
        await InvokeAsync<object?>(callbackId, args, cancellationToken).ConfigureAwait(false);
    }
}

View on GitHub (pinned to 25830f84bd)