dotnet/aspnetcore · error · IllegalArgumentException
Expected either 'error' or 'result' to be provided, but not
Error message
Expected either 'error' or 'result' to be provided, but not both.
What it means
CompletionMessage's constructor enforces the hub protocol invariant that a completion carries either an error or a result, but never both. Passing both non-null is contradictory (success vs failure) and would violate the wire contract.
Source
Thrown at src/SignalR/clients/java/signalr/core/src/main/java/com/microsoft/signalr/CompletionMessage.java:20
// The .NET Foundation licenses this file to you under the MIT license.
package com.microsoft.signalr;
import java.util.Map;
public final class CompletionMessage extends HubMessage {
private final int type = HubMessageType.COMPLETION.value;
private Map<String, String> headers;
private final String invocationId;
private final Object result;
private final String error;
public CompletionMessage(Map<String, String> headers, String invocationId, Object result, String error) {
if (headers != null && !headers.isEmpty()) {
this.headers = headers;
}
if (error != null && result != null) {
throw new IllegalArgumentException("Expected either 'error' or 'result' to be provided, but not both.");
}
this.invocationId = invocationId;
this.result = result;
this.error = error;
}
public Map<String, String> getHeaders() {
return headers;
}
public Object getResult() {
return result;
}
public String getError() {
return error;
}
View on GitHub (pinned to 294cab2f9b)
Solutions
- Pass exactly one of result or error; leave the other null.
- Centralize CompletionMessage construction in a factory that enforces the invariant.
- Add an assertion in your builder so both-non-null fails earlier with a clearer message.
- If you need to represent 'result with warning', put the warning elsewhere (e.g. headers), not in error.
Example fix
// before new CompletionMessage(null, invocationId, result, "warn"); // both set // after new CompletionMessage(null, invocationId, result, null);
Defensive patterns
Strategy: validation
Validate before calling
static CompletionMessage build(String id, Object result, String error) {
if (result != null && error != null) {
throw new IllegalArgumentException("Provide result OR error, not both");
}
return new CompletionMessage(null, id, result, error);
} Prevention
- Use a single factory for CompletionMessage that enforces the invariant.
- In tests, never set both result and error.
- Route warnings through headers instead of the error field.
When it happens
Trigger: Constructing CompletionMessage manually with both error and result non-null, typically in tests, custom protocol layers, or hand-built message factories.
Common situations: Unit tests building fixtures incorrectly, a custom hub/protocol wrapper that sets both fields, or copy-paste leaving a stale error alongside a result.
Related errors
- Invalid payload for Completion message.
- Invocation provides %d argument(s) but target expects %d.
- Invalid input for JSON hub protocol. Expected a string.
- Invalid payload.
- Invalid payload for StreamItem message.
AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06).
Data as JSON: /api/errors/48636df05c0d5089.
Report an issue: GitHub.