dotnet/aspnetcore · error · IllegalStateException

Invocation Id is already used

Error message

Invocation Id is already used

What it means

An IllegalStateException thrown by ConnectionState.addInvocation when an InvocationRequest with the same invocationId already exists in pendingInvocations. Invocation IDs are generated monotonically via AtomicInteger (getNextInvocationId), so a duplicate under normal single-connection usage is an internal invariant violation indicating the ID generator wrapped or state corrupted.

Source

Thrown at src/SignalR/clients/java/signalr/core/src/main/java/com/microsoft/signalr/HubConnection.java:1437

                for (String key : keys) {
                    if (ex == null) {
                        pendingInvocations.get(key).cancel();
                    } else {
                        pendingInvocations.get(key).fail(ex);
                    }
                }

                pendingInvocations.clear();
            } finally {
                lock.unlock();
            }
        }

        public void addInvocation(InvocationRequest irq) {
            lock.lock();
            try {
                if (pendingInvocations.containsKey(irq.getInvocationId())) {
                    throw new IllegalStateException("Invocation Id is already used");
                } else {
                    pendingInvocations.put(irq.getInvocationId(), irq);
                }
            } finally {
                lock.unlock();
            }
        }

        public InvocationRequest getInvocation(String id) {
            lock.lock();
            try {
                return pendingInvocations.get(id);
            } finally {
                lock.unlock();
            }
        }

        public InvocationRequest tryRemoveInvocation(String id) {

View on GitHub (pinned to 294cab2f9b)

Solutions

  1. If reproduced in test code, stop manually setting invocation IDs; let getNextInvocationId generate them.
  2. In production, this indicates a library-level issue; report with a repro and the connection lifecycle trace.
  3. Restart the HubConnection (stop + start) to reset the ID counter and clear pendingInvocations.

Example fix

// before (test): manual duplicate id
String id = "1";
connectionState.addInvocation(new InvocationRequest(null, id));
connectionState.addInvocation(new InvocationRequest(null, id)); // throws

// after: let the connection generate unique ids
String id = connectionState.getNextInvocationId();
connectionState.addInvocation(new InvocationRequest(null, id));
Defensive patterns

Strategy: try-catch

Validate before calling

// No public pre-check; this is an internal invariant. The practical guard is to never
// manually inject invocation IDs and to restart the connection if it occurs.
if (connection.getConnectionState() != HubConnectionState.CONNECTED) {
    // don't invoke; avoids internal state corruption
}

Try / catch

try {
    connection.invoke("method").blockingAwait();
} catch (IllegalStateException e) {
    if (e.getMessage().contains("Invocation Id is already used")) {
        // internal ID collision; restart the connection to reset state
        connection.stop().blockingAwait();
        connection.start().blockingAwait();
    } else { throw e; }
}

Prevention

When it happens

Trigger: addInvocation(irq) is called with an id already present in pendingInvocations. In practice this requires the nextId AtomicInteger to produce a value that collides with a still-pending request, which should not happen in correct single-connection operation. Could be triggered by manual id injection in tests or by reusing a HubConnection's internal ConnectionState across logical connections.

Common situations: Test code that manually constructs InvocationRequest objects and calls addInvocation with hardcoded ids. A long-lived connection whose integer ID counter is theoretically approaching limits (unlikely). Concurrent invoke/stream calls racing through getNextInvocationId in a way that, combined with a bug, reuses an id. Generally an internal/library bug if seen in production.

Related errors


AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06). Data as JSON: /api/errors/388d46be9d13dcb2. Report an issue: GitHub.