microsoft/aspire · error · AbortError
The operation was aborted before it was sent to the AppHost.
Error message
The operation was aborted before it was sent to the AppHost.
What it means
When an operation is called with an AbortSignal/abort token, the transport first checks whether the signal is already aborted before registering cancellation with the AppHost. If it is, the operation can never meaningfully start, so registerCancellation throws immediately instead of sending a doomed request. This is an early-exit guard, not a timeout.
Solutions
- Check `signal.aborted` before invoking and skip the call entirely if already aborted.
- Create a fresh AbortController per operation instead of reusing an aborted signal.
- If abort-before-call is expected, catch the error and treat it as a no-op/cancelled result.
- Only abort signals after the operation has been initiated if you want mid-flight cancellation (handled by a different path).
Example fix
// before
const controller = new AbortController();
controller.abort();
await client.capability('build', { signal: controller.signal }); // throws
// after
const controller = new AbortController();
if (!controller.signal.aborted) {
await client.capability('build', { signal: controller.signal });
} Defensive patterns
Strategy: try-catch
Validate before calling
if (signal?.aborted) {
return; // skip the call entirely — it can never be sent
} Type guard
const isLiveSignal = (s?: AbortSignal): s is AbortSignal => s instanceof AbortSignal && !s.aborted;
Try / catch
try {
await client.capability('build', { signal });
} catch (e) {
if (String((e as Error).message).includes('aborted before it was sent')) {
return; // treat as cancelled no-op, not a failure
}
throw e;
} Prevention
- Create a fresh AbortController per operation instead of reusing signals.
- Check signal.aborted before initiating any AppHost call.
- Only abort after the operation has started if you intend mid-flight cancellation.
- Audit shared CancellationTokenSources for earlier aborts before reuse.
When it happens
Trigger: Passing an AbortSignal (or cancellation token) that is already aborted to a transport operation, e.g. `client.op(args, { signal: controller.signal })` after `controller.abort()` was called, or reusing a signal from an already-completed/aborted request.
Common situations: A request scope was cancelled upstream (HTTP request aborted, user navigated away) before the AppHost call was made; a shared CancellationTokenSource aborted by an earlier failure; racing user cancellation with the call setup.
Related errors
- Argument ' ' passed to capability ' ' is a Promise-like…
- AspireDict must be resolved before it can be serialized…
- AspireList must be resolved before it can be serialized…
- Flushing pending promise(s). Consider awaiting fluent calls…
- registerCancellation(signal) is ambiguous when multiple…
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/c5fa28f70f9ba95e.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.CodeGeneration.TypeScript/Resources/transport.mts:652
): string | undefined {
const client = isAspireClientLike(clientOrSignalOrToken) ? clientOrSignalOrToken : undefined;
const signalOrToken = client
? maybeSignalOrToken
: clientOrSignalOrToken as AbortSignal | CancellationToken | undefined;
if (!signalOrToken) {
return undefined;
}
if (isCancellationTokenLike(signalOrToken)) {
return signalOrToken.register(client);
}
const signal = signalOrToken;
const cancellationClient = resolveCancellationClient(client);
if (signal.aborted) {
throw createAbortError('The operation was aborted before it was sent to the AppHost.');
}
const cancellationId = `ct_${++cancellationIdCounter}_${Date.now()}`;
// Set up the abort listener
const onAbort = () => {
// Send cancel request to host
if (cancellationClient.connected) {
cancellationClient.cancelToken(cancellationId).catch(() => {
// Ignore errors - the operation may have already completed
});
}
// Clean up the listener
cancellationRegistry.delete(cancellationId);
};
// Listen for abort
signal.addEventListener('abort', onAbort, { once: true });View on GitHub (pinned to 25830f84bd)