mgth/LittleBigMouse · error · InvalidOperationException

The VIDAA connection is not open.

Error message

The VIDAA connection is not open.

What it means

AuthenticateAsync sends the PIN to the Hisense VIDAA device over an MQTT session. It throws InvalidOperationException because the underlying session is not connected — pairing cannot proceed on a closed connection. The library guards up front rather than letting the publish fail obscurely mid-handshake.

Solutions

  1. Call session.EnsureOpenAsync(ct) (or check session.Connected) before calling AuthenticateAsync
  2. Await the EnsureOpenAsync/OpenAsync task and propagate its exceptions before the PIN flow
  3. Re-open the session and retry AuthenticateAsync once if the connection dropped mid-flow
  4. Check network/reachability of the projector if Connected stays false

Example fix

// before
await pairing.AuthenticateAsync(pin, ct);
// after
await session.EnsureOpenAsync(ct);
await pairing.AuthenticateAsync(pin, ct);
Defensive patterns

Strategy: try-catch

Validate before calling

if (!session.Connected)
    await session.EnsureOpenAsync(ct);
await pairing.AuthenticateAsync(pin, ct);

Type guard

bool CanAuthenticate(IVidaaSession session) => session.Connected;

Try / catch

try
{
    await pairing.AuthenticateAsync(pin, ct);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("VIDAA connection is not open"))
{
    await session.EnsureOpenAsync(ct);
    await pairing.AuthenticateAsync(pin, ct); // retry once
}

Prevention

When it happens

Trigger: Calling AuthenticateAsync(pin) before VidaaSession.EnsureOpenAsync/OpenAsync has established the MQTT connection, or after the connection dropped (device rebooted, network loss, session closed by another code path).

Common situations: App skips the EnsureOpenAsync step and goes straight to PIN entry; device disconnected while user was typing the on-screen PIN; a previous authentication failure closed the session; connection lost due to projector standby.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of mgth/LittleBigMouse@7a42f01d47 (2026-09-16). Data as JSON: /api/errors/a1d1ddd8e0bdd075. Report an issue: GitHub.

Appendix: source

Thrown at LittleBigMouse.Plugins/LittleBigMouse.Plugin.Vcp.Avalonia/HisenseVidaa/VidaaPairing.cs:51

    public async Task StartAsync(bool requestPin, CancellationToken cancellationToken)
    {
        if (string.IsNullOrWhiteSpace(configuration.ControllerMacAddress))
            configuration.ControllerMacAddress = NetworkIdentity.ControllerMacFor(configuration.IpAddress);

        if (HisenseVidaaProtocol.UsesStaticLegacyProtocol(configuration.ProtocolVersion))
            await StartLegacyAsync(requestPin, cancellationToken).ConfigureAwait(false);
        else
            await StartDynamicAsync(requestPin, cancellationToken).ConfigureAwait(false);
    }

    /// <summary>
    /// Sends the PIN the device displays. On RemoteNOW that is the whole pairing; newer devices
    /// answer it with an access token, which the router stores as it arrives.
    /// </summary>
    public async Task AuthenticateAsync(string pin, CancellationToken cancellationToken)
    {
        if (!session.Connected)
            throw new InvalidOperationException("The VIDAA connection is not open.");

        var legacy = HisenseVidaaProtocol.UsesStaticLegacyProtocol(configuration.ProtocolVersion);
        var pinAccepted = responses.PinAccepted.Expect();
        var tokenIssued = responses.TokenIssued.Expect();
        await session.PublishAsync(
            HisenseVidaaProtocol.Topic("ui_service", configuration.ClientId, "authenticationcode"),
            legacy ? HisenseVidaaProtocol.LegacyPinPayload(pin) : HisenseVidaaProtocol.PinPayload(pin),
            cancellationToken).ConfigureAwait(false);

        await pinAccepted.WaitAsync(AnswerTimeout, cancellationToken).ConfigureAwait(false);
        if (legacy)
        {
            configuration.LegacyAuthorized = true;
            return;
        }

        await session.PublishAsync(
            HisenseVidaaProtocol.TokenRequestTopic(configuration.ClientId),

View on GitHub (pinned to 7a42f01d47)