microsoft/aspire · error · Error

registerCancellation(signal) requires a connected…

Error message

registerCancellation(signal) requires a connected AspireClient. Pass the client explicitly or connect the client first.

What it means

resolveCancellationClient picks the AspireClient to use for registerCancellation(signal). With zero connected clients there is nothing to register cancellation against, so it throws and asks the caller to either pass the client explicitly or connect one first.

Solutions

  1. Pass the AspireClient explicitly: registerCancellation(signal, client).
  2. Await client.connect() (and confirm it succeeded) before calling registerCancellation.
  3. Re-check connection lifecycle ordering in startup code.
  4. In tests, create and connect a client (or fake server) before registering cancellation.

Example fix

// before
registerCancellation(abortController.signal); // no client connected

// after
const client = new AspireClient();
await client.connect();
registerCancellation(abortController.signal, client);
Defensive patterns

Strategy: validation

Validate before calling

if (!client || !client.isConnected?.()) {
  throw new Error("Connect an AspireClient before registerCancellation, or pass the client explicitly");
}
registerCancellation(signal, client);

Type guard

function isConnectedClient(c: unknown): c is AspireClient {
  return c instanceof AspireClient && (c as { connected?: boolean }).connected === true;
}

Try / catch

try {
  registerCancellation(signal);
} catch (e) {
  if (e instanceof Error && e.message.includes("requires a connected AspireClient")) {
    await client.connect();
    registerCancellation(signal, client);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling registerCancellation(signal) before any AspireClient.connect() has completed; the client disconnected before registration; forgetting to pass an explicit client in a context with no ambient connection.

Common situations: Setting up cancellation at module top level before the connection is established; connection failure earlier in startup leaving zero clients; tests that never connect a client.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting.CodeGeneration.TypeScript/Resources/transport.mts:575

/**
 * Registry for cancellation tokens.
 * Maps cancellation IDs to cleanup functions.
 */
const cancellationRegistry = new Map<string, () => void>();
let cancellationIdCounter = 0;
const connectedClients = new Set<AspireClient>();

function resolveCancellationClient(client?: AspireClientRpc): AspireClientRpc {
    if (client) {
        return client;
    }

    if (connectedClients.size === 1) {
        return connectedClients.values().next().value as AspireClient;
    }

    if (connectedClients.size === 0) {
        throw new Error(
            'registerCancellation(signal) requires a connected AspireClient. ' +
            'Pass the client explicitly or connect the client first.'
        );
    }

    throw new Error(
        'registerCancellation(signal) is ambiguous when multiple AspireClient instances are connected. ' +
        'Pass the client explicitly.'
    );
}

function isAspireClientLike(value: unknown): value is AspireClientRpc {
    if (!value || typeof value !== 'object') {
        return false;
    }

    const candidate = value as {
        invokeCapability?: unknown;

View on GitHub (pinned to 25830f84bd)