dotnet/aspnetcore · error · RuntimeException

Invocation provides argument(s) but target expects .

Error message

Invocation provides %d argument(s) but target expects %d.

What it means

In bindArguments the count of arguments read off the wire is compared against the number of parameter types the InvocationBinder reported for the target method. A mismatch means the client registered a handler whose signature does not match what the server is sending for that hub method.

Solutions

  1. Update the client hubConnection.on(...) registration so its parameter type list exactly matches the server hub method's current signature.
  2. Verify the target method name string matches the server method exactly (case-sensitive).
  3. Redeploy both client and server from the same shared contract/Interface assembly where possible.

Example fix

// before - server now sends 2 args, client registered 1
hubConnection.on("SendMessage", (user) -> {...}, String.class);
// after
hubConnection.on("SendMessage", (user, message) -> {...}, String.class, String.class);
Defensive patterns

Strategy: validation

Validate before calling

// Mirror the server hub method's parameter list exactly when registering
Class<?>[] serverParams = { String.class, String.class };
if (serverParams.length != expectedArgCount) {
    throw new IllegalStateException("Signature drift: " + serverParams.length);
}
hubConnection.on("SendMessage", (a, b) -> {}, serverParams);

Type guard

static boolean signaturesMatch(Class<?>[] registered, int serverArgCount) {
    return registered != null && registered.length == serverArgCount;
}

Try / catch

// bindArguments failure is wrapped by the protocol into InvocationBindingFailureMessage for
// invocations (not thrown), so for invocations check the returned message type:
List<HubMessage> msgs = protocol.parseMessages(buf, binder);
for (HubMessage m : msgs) {
    if (m.getMessageType() == HubMessageType.INVOCATION_BINDING_FAILURE) {
        // log and reconcile the signature mismatch
    }
}

Prevention

When it happens

Trigger: The server invokes a hub method with N arguments but the client's binder (built from hubConnection.on(target, ...paramTypes)) declared M != N parameter types. The check at MessagePackHubProtocol.java:514-516 fails before any argument is decoded.

Common situations: Server hub method signature changed (params added/removed) without updating the client handler, wrong number of argument types passed to hubConnection.on(...), or a typo in the target method name binding to the wrong overload.

Related errors


AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11). Data as JSON: /api/errors/67423b486c1cd978. Report an issue: GitHub.

Appendix: source

Thrown at src/SignalR/clients/java/signalr/messagepack/src/main/java/com/microsoft/signalr/messagepack/MessagePackHubProtocol.java:515

        return streams;
    }

    private void writeStreamIds(Collection<String> streamIds, MessagePacker packer) throws IOException {
        if (streamIds != null) {
            packer.packArrayHeader(streamIds.size());
            for (String s: streamIds) {
                packer.packString(s);
            }
        } else {
            packer.packArrayHeader(0);
        }
    }

    private Object[] bindArguments(MessageUnpacker unpacker, List<Type> paramTypes, ByteBuffer payload) throws IOException {
        int argumentCount = unpacker.unpackArrayHeader();

        if (paramTypes.size() != argumentCount) {
            throw new RuntimeException(String.format("Invocation provides %d argument(s) but target expects %d.", argumentCount, paramTypes.size()));
        }

        Object[] arguments = new Object[argumentCount];

        for (int i = 0; i < argumentCount; i++) {
            arguments[i] = readValue(unpacker, paramTypes.get(i), payload, true);
        }

        return arguments;
    }

    private Object readValue(MessageUnpacker unpacker, Type itemType, ByteBuffer payload, boolean outermostCall) throws IOException {
        Class<?> itemClass = Utils.typeToClass(itemType);
        MessageFormat messageFormat = unpacker.getNextFormat();
        ValueType valueType = messageFormat.getValueType();
        int length;
        long readBytesStart;
        Object item = null;

View on GitHub (pinned to 3600ca084e)