mgth/LittleBigMouse · error · System.UnauthorizedAccessException

{channelEvent.Error}

Error message

{channelEvent.Error}

What it means

EnsureConnectedLockedAsync reads JSON WebSocket messages from a Samsung Tizen TV and parses each into a channel event via SamsungTizenProtocol.ParseChannelEvent. When the event carries a non-empty Error field, the device-side pairing/connection failed, and the client surfaces that remote message verbatim via PairingException(channelEvent.Error). The exception text is whatever the TV reported (e.g. 'unrecognized method', 'invalid pin', 'timeout').

Solutions

  1. Read the embedded Error text (it is the exception message) and act on it: retry ConnectAsync and accept the on-screen Allow prompt within the timeout.
  2. Delete the stored token and re-pair from scratch: reset _token / clear the saved SamsungTizen configuration so a fresh PIN prompt is issued.
  3. If the error is about an unrecognized method, update SamsungTizenProtocol step payloads to match the current Tizen firmware's expected step/method names.
  4. Ensure SendKeyAsync is only called after a successful EnsureConnectedLockedAsync (channelEvent.Connected).

Example fix

// before
await client.SendKeyAsync("KEY_POWER"); // throws PairingException("unrecognized method 800.unrecognized")
// after
try { await client.EnsureConnectedLockedAsync(ct); await client.SendKeyAsync("KEY_POWER"); }
catch (Exception e) when (e.Message.Contains("unrecognized")) {
    client.ResetToken();          // discard stale token
    await client.ConnectAsync(ct); // re-pair, accept prompt on TV
}
Defensive patterns

Strategy: try-catch

Validate before calling

// track token freshness yourself
if (string.IsNullOrEmpty(_token) && tokenRejectedAt > DateTimeOffset.Now.AddMinutes(-5))
    throw new InvalidOperationException("Tizen pairing recently failed; clear token and re-pair before sending keys.");

Try / catch

try { await client.EnsureConnectedLockedAsync(ct); }
catch (Exception e) when (e.Message.Contains("unrecognized") || e.Message.Contains("invalid")) {
    _token = null;              // discard stale token
    await client.ConnectAsync(ct); // full re-pair; user must accept TV prompt
}

Prevention

When it happens

Trigger: Calling EnsureConnectedLockedAsync (via ConnectAsync, SendKeyAsync, or ReopenAsync) while the WebSocket is open and the TV responds to the connect/step payload with {"error": ...} — e.g. the user denied the pairing prompt, the PIN/token step timed out, or an unknown method value was sent.

Common situations: User dismissed or let the TV's 'Allow' prompt expire; a stale token is rejected after the TV revoked the app; TV firmware changed the protocol method names; calling SendKeyAsync before pairing completed.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at LittleBigMouse.Plugins/LittleBigMouse.Plugin.Vcp.Avalonia/SamsungTizen/SamsungTizenClient.cs:57

        socket.Options.KeepAliveInterval = TimeSpan.FromSeconds(20);

        // Samsung uses a device-generated certificate. Restricting the connection to the
        // explicitly selected IPv4 address prevents this exception from becoming a general
        // trust policy for the application.
        socket.Options.RemoteCertificateValidationCallback = (_, _, _, _) => true;
        _socket = socket;

        try
        {
            await socket.ConnectAsync(SamsungTizenProtocol.RemoteUri(ipAddress, _token), cancellationToken)
                .ConfigureAwait(false);

            while (socket.State == WebSocketState.Open)
            {
                var message = await ReceiveTextLockedAsync(cancellationToken).ConfigureAwait(false);
                var channelEvent = SamsungTizenProtocol.ParseChannelEvent(message);
                if (!string.IsNullOrEmpty(channelEvent.Error))
                    throw PairingException(channelEvent.Error);
                if (!channelEvent.Connected) continue;

                if (!string.IsNullOrWhiteSpace(channelEvent.Token)) _token = channelEvent.Token;
                return;
            }

            throw new WebSocketException("The Samsung display closed the pairing channel.");
        }
        catch (OperationCanceledException)
        {
            ResetSocketLocked();
            throw;
        }
        catch (UnauthorizedAccessException)
        {
            ResetSocketLocked();
            throw;
        }

View on GitHub (pinned to 7a42f01d47)