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
- Update the client hubConnection.on(...) registration so its parameter type list exactly matches the server hub method's current signature.
- Verify the target method name string matches the server method exactly (case-sensitive).
- 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
- Share the hub interface/contract between client and server.
- Update client handler registrations whenever the server method signature changes.
- Use the exact, case-sensitive target method name.
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
- Cannot handle type class
- Error reading length header.
- Error reading MessagePack data.
- Error writing MessagePack data.
- Extension types are not supported
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)