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

GsonHubProtocol binds incoming invocation arguments to the parameter types declared when the handler was registered (hubConnection.on(target, action, Type...)). bindArguments requires the argument count from the server to exactly equal the registered parameter count; any mismatch throws.

Source

Thrown at src/SignalR/clients/java/signalr/core/src/main/java/com/microsoft/signalr/GsonHubProtocol.java:233

                    default:
                        break;
                }
            }
        } catch (IOException ex) {
            throw new RuntimeException("Error reading JSON.", ex);
        }

        return hubMessages;
    }

    @Override
    public ByteBuffer writeMessage(HubMessage hubMessage) {
        return ByteBuffer.wrap((gson.toJson(hubMessage) + RECORD_SEPARATOR).getBytes(StandardCharsets.UTF_8));
    }

    private ArrayList<Object> bindArguments(JsonArray argumentsToken, List<Type> paramTypes) {
        if (argumentsToken.size() != paramTypes.size()) {
            throw new RuntimeException(String.format("Invocation provides %d argument(s) but target expects %d.", argumentsToken.size(), paramTypes.size()));
        }

        ArrayList<Object> arguments = null;
        if (paramTypes.size() >= 1) {
            arguments = new ArrayList<>();
            for (int i = 0; i < paramTypes.size(); i++) {
                arguments.add(gson.fromJson(argumentsToken.get(i), paramTypes.get(i)));
            }
        }

        return arguments;
    }

    private ArrayList<Object> bindArguments(JsonReader reader, List<Type> paramTypes) throws IOException {
        reader.beginArray();
        int paramCount = paramTypes.size();
        int argCount = 0;
        ArrayList<Object> arguments = new ArrayList<>();

View on GitHub (pinned to 294cab2f9b)

Solutions

  1. Update the client hubConnection.on(...) so the number of declared types matches the server method's parameters exactly.
  2. If the server legitimately changed signature, release matching client/server versions together.
  3. Double-check that every parameter has a corresponding Type argument in on(target, action, Type...).
  4. Inspect the raw arguments array in the wire message to confirm the server-side count.

Example fix

// before
hubConnection.on("Send", (String a) -> { ... }, String.class); // 1 type
// server invokes "Send" with (String a, int b)

// after
hubConnection.on("Send", (String a, Integer b) -> { ... }, String.class, Integer.class);
Defensive patterns

Strategy: validation

Validate before calling

// before registering, confirm the handler arity matches the server contract
void on(String target, Action action, Type... types) {
  if (types.length != expectedServerParamCount(target)) {
    throw new IllegalArgumentException("Parameter count mismatch for " + target);
  }
  hubConnection.on(target, action, types);
}

Try / catch

try {
  hubConnection.on("Send", (String a, Integer b) -> {}, String.class, Integer.class);
} catch (RuntimeException e) {
  if (e.getMessage().contains("argument(s) but target expects")) {
    // adjust the declared Type... count to match the server
  }
}

Prevention

When it happens

Trigger: Server invokes a hub method with N arguments but the client registered on("Method", action, types...) with M types where N != M. For example server sends 2 args but client registered a single-parameter handler.

Common situations: Server hub method signature changed (args added/removed) but the client was not updated; the on(...) call omitted a Type; or the server invokes with default/extra params the client does not expect.

Related errors


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