mgth/LittleBigMouse · error · InvalidOperationException
Pair this Hisense VIDAA device first.
Error message
Pair this Hisense VIDAA device first.
What it means
EnsureOpenAsync opens the MQTT session described by the stored pairing, but throws InvalidOperationException when the configuration contains no pairing at all — the device has never completed the pairing handshake, so there are no credentials/topics to open the session with. The XML docs declare this contract explicitly.
Solutions
- Run the pairing flow first: open a pairing session, call AuthenticateAsync with the on-screen PIN, and let the access token be stored
- Check configuration.HasPairing before attempting to use the session and route to the pairing UI otherwise
- If the device was factory-reset, delete the stale config and re-pair
- Restore/verify the stored pairing configuration file wasn't lost or emptied
Example fix
// before
await session.EnsureOpenAsync(ct);
await session.SendAsync(keyCmd, ct);
// after
if (!configuration.HasPairing)
await pairingUi.RunPairingAsync(ct); // stores the token
await session.EnsureOpenAsync(ct); Defensive patterns
Strategy: validation
Validate before calling
if (!configuration.HasPairing)
{
ShowPairingUi(); // run AuthenticateAsync flow to obtain and store token
return;
}
await session.EnsureOpenAsync(ct); Type guard
bool IsPaired(VidaaConfiguration config) => config.HasPairing;
Prevention
- Gate all session usage behind a HasPairing check that routes to the pairing UI
- Re-pair automatically after device factory reset (stale pairing is rejected)
- Persist pairing config reliably and verify it on startup
- Never call SendAsync/ReopenAsync on a brand-new session before pairing
When it happens
Trigger: Calling EnsureOpenAsync (directly or via SendAsync/ReopenAsync) on a VidaaSession whose configuration.HasPairing is false — i.e. before AuthenticateAsync/pairing ever succeeded or after pairing data was cleared.
Common situations: Fresh install pointing at a device that was never paired; pairing data wiped (config reset, reinstalled app, device factory reset); trying to send keys/queries before running the pairing flow; tests exercising an unpaired session.
Related errors
- The VIDAA connection is not open.
- VIDAA rejected every authentication variant for protocol
- The VIDAA connection is not open.
- No VIDAA descriptor answered at
- Enter a valid projector IPv4 address.
AI-assisted analysis of mgth/LittleBigMouse@7a42f01d47 (2026-09-16).
Data as JSON: /api/errors/2c8d83fed9336b15.
Report an issue: GitHub.
Appendix: source
Thrown at LittleBigMouse.Plugins/LittleBigMouse.Plugin.Vcp.Avalonia/HisenseVidaa/VidaaSession.cs:52
IReadOnlyList<string> topics,
CancellationToken cancellationToken)
{
await CloseAsync().ConfigureAwait(false);
var connection = await _transport(
VidaaConnectionProfile.Request(configuration, credentials), cancellationToken)
.ConfigureAwait(false);
connection.MessageReceived += Dispatch;
_connection = connection;
await connection.SubscribeAsync(topics, cancellationToken).ConfigureAwait(false);
}
/// <summary>Opens the session the stored pairing describes, unless one is already open.</summary>
/// <exception cref="InvalidOperationException">The device has never been paired.</exception>
public async Task EnsureOpenAsync(CancellationToken cancellationToken)
{
if (Connected) return;
if (!configuration.HasPairing)
throw new InvalidOperationException("Pair this Hisense VIDAA device first.");
await OpenAsync(
VidaaConnectionProfile.StoredCredentials(configuration),
VidaaConnectionProfile.ResponseTopics(configuration),
cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// Publishes on the paired session, opening it if needed and giving the command a second
/// chance when the write is what reveals the broker dropped the previous one. See
/// <see cref="StaleConnectionRetry"/>; here a dead session has to be closed before the
/// stored pairing can open another.
/// </summary>
public async Task SendAsync(string topic, string payload, CancellationToken cancellationToken)
{
await EnsureOpenAsync(cancellationToken).ConfigureAwait(false);
await StaleConnectionRetry.SendAsync(
token => PublishAsync(topic, payload, token),View on GitHub (pinned to 7a42f01d47)