Skip to content

Desktop app: unhandled UI broadcasts raise InvalidDataException in the SignalR client #1046

Description

@alexeyzimarev

The desktop app raises a first-chance System.IO.InvalidDataException for every UI broadcast it receives but does not handle, if the broadcast carries an argument.

Evidence (Debug build, macOS, 2026-09-19): dotnet-counters on the running app showed dotnet.exceptions[error.type=InvalidDataException] ticking; a temporary FirstChanceException hook printed the same stack four times in 45 s during ordinary session activity:

InvalidDataException: Invocation provides 1 argument(s) but target expects 0.
   at Microsoft.AspNetCore.SignalR.Protocol.JsonHubProtocol.BindTypes(Utf8JsonReader& reader, IReadOnlyList`1 paramTypes)

Cause. The app connects to /hubs/sessions (ServerConnectionService) and the server puts it in the UI clients group, so it receives every Clients.UiClients().SendAsync(...) broadcast — PermissionPending(sessionId), PermissionResponded(sessionId, requestId), ActiveSessionAdded/Changed/Removed(sessionId), SessionTitleChanged(sessionId), SubagentAdopted(sessionId), SessionDeleted(sessionId), LaunchFailed(agentId, reason) and the rest of Broadcast/UiBroadcast.cs on the server. The app registers no handler for any of them (its only handlers are the Eventuous client's StreamEvent/StreamError). For a target with no handler, HubConnection.GetParameterTypes returns Type.EmptyTypes (Microsoft.AspNetCore.SignalR.Client.Core 10.0.12), so JsonHubProtocol.BindTypes throws on any argument; the client catches it as an InvocationBindingFailureMessage and drops the message. Payload-less nudges (AgentInstancesChanged, DaemonsChanged) bind cleanly and are dropped without an exception.

Impact. Functionally none today — the app consumes streams through Eventuous and ignores the nudges. The cost is one thrown-and-caught exception per unhandled broadcast (stack capture on the SignalR receive loop) plus a Debug-level "Failed to bind arguments" log line, at whatever rate hooks and session changes produce broadcasts across the tenant; it also makes InvalidDataException useless as a signal when profiling the app.

Options.

  1. Register handlers for the broadcasts the app can use (ActiveSessionChanged, SessionTitleChanged, PermissionPending/PermissionResponded are all things the rail and chat could refresh on) and no-op handlers for the rest, with a test that every name in UiBroadcast.cs has a registration.
  2. Have the server not enrol a connection in the UI clients group unless it asks to (the app never needs the nudges while it tails streams).
  3. Leave it and document it as expected noise.

Found while profiling the glass material branch (#1035); unrelated to it.

Activity

  1. linear-code commented on Sep 19, 2026

    @linear-code
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions