dotnet/aspnetcore · error · RuntimeException
Invocation provides %d argument(s) but target expects %d.
Error message
Invocation provides %d argument(s) but target expects %d.
What it means
bindArguments compares the number of arguments in the incoming InvocationMessage against the number of parameter types the InvocationBinder returns for the target hub method. They must be equal; otherwise the invocation cannot be bound and a RuntimeException is thrown.
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 294cab2f9b)
Solutions
- Align the number of arguments sent with the hub method's parameter count.
- For .on(...) client methods, register a callback whose arity matches what the server sends.
- Rebuild and redeploy both sides after any hub signature change.
Example fix
// before
// server: public void Add(int a) {}
hubConnection.send("Add", 1, 2);
// after
hubConnection.send("Add", 1); Defensive patterns
Strategy: validation
Validate before calling
// Java - confirm arity before invoking
java.lang.reflect.Method m = hubMethods.get(target);
if (m != null && m.getParameterCount() != args.length) {
throw new IllegalArgumentException("Argument count mismatch for " + target);}
Try / catch
// Java
hubConnection.on("Method", (a, b) -> {}, String.class, String.class);
try {
hubConnection.send("Method", "one").blockingAwait();
} catch (RuntimeException ex) {
if (ex.getMessage() != null && ex.getMessage().contains("argument(s) but target expects")) {
}
} Prevention
- Keep the number of arguments sent equal to the hub method's parameter count.
- Register .on(...) callbacks with an arity matching what the server sends.
- Redeploy both sides after any hub method signature change.
When it happens
Trigger: Client invokes a server hub method with N args but the method is defined with M; server invokes a client method registered via .on(...) with a different arg count; a hub method signature was changed on one side only.
Common situations: Hub method signature refactored without updating clients; client-side .on(...) handler registered with the wrong parameter list; version skew between deployed server and client.
Related errors
- Cannot read message size.
- Messages bigger than 2GB are not supported.
- Incomplete message.
- MessagePack message was length %d but claimed to be length %
- Error reading length header.
AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06).
Data as JSON: /api/errors/67423b486c1cd978.
Report an issue: GitHub.