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

Thrown by GsonHubProtocol.bindArguments (the JsonArray-based path) when the number of JSON arguments in an invocation does not equal the number of parameter types the registered handler expects. The client is about to gson.fromJson each argument into its target Type and rejects a count mismatch up front to avoid silent misbinding.

Solutions

  1. Match the hubConnection.on(...) Type list to the server method's current parameter list - count and order.
  2. Update the client when the server method signature changes; version-pin if you cannot deploy both at once.
  3. Inspect the inbound invocation's arguments array length and compare to the registered Type[] length.

Example fix

// before
// C# hub: public void Send(string a, string b, int c)
// Java: hubConnection.on("Send", (a, b) -> {}, String.class, String.class); // 2 vs 3 -> throws

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

Strategy: validation

Validate before calling

void register(HubConnection conn, String target, Type[] expected, Action<Object[]> handler) {
  // expected[] is the documented server-side parameter list
  conn.on(target, args -> handler.call(args), expected); // lengths are now in sync by construction
}

Type guard

boolean arityMatches(Type[] registered, int wireArgCount) {
  return registered.length == wireArgCount;
}

Try / catch

try {
  conn.on("Send", h, String.class, Integer.class);
} catch (RuntimeException e) {
  if (e.getMessage() != null && e.getMessage().contains("argument(s) but target expects")) {
    // update the Type[] to match the current server method signature
  } else throw e;
}

Prevention

When it happens

Trigger: Server invokes a client method with N arguments but the Java handler registered for that target has M parameters (N != M). The handler's parameter Types come from hubConnection.on('target', (a, b) -> ..., Type1.class, Type2.class); the arguments come from the wire's 'arguments' array.

Common situations: Server hub method signature changed (added/removed a parameter) but the client registration was not updated; client registered with the wrong number of Type tokens; the server sends default/null arguments that still count toward the array size.

Related errors


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

Appendix: 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 3600ca084e)