{"record":{"id":"83485c5a34447947","repo":"mgth/LittleBigMouse","slug":"enter-a-valid-projector-ipv4-address","errorCode":null,"errorMessage":"Enter a valid projector IPv4 address.","messagePattern":"Enter a valid projector IPv4 address\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"LittleBigMouse.Plugins/LittleBigMouse.Plugin.Vcp.Avalonia/HisenseVidaa/HisenseVidaaDiscovery.cs","lineNumber":53,"sourceCode":"                lastError = e;\n            }\n            catch (HttpRequestException e)\n            {\n                lastError = e;\n            }\n        }\n\n        throw new HttpRequestException(\n            $\"No VIDAA descriptor answered at {ipAddress} on ports {string.Join('/', HisenseVidaaProtocol.DescriptorPorts)}.\",\n            lastError);\n    }\n\n    public async Task<HisenseVidaaDevice> FindAsync(\n        string lastKnownAddress,\n        CancellationToken cancellationToken = default)\n    {\n        if (!Ipv4Address.TryParse(lastKnownAddress, out var seed))\n            throw new ArgumentException(\"Enter a valid projector IPv4 address.\", nameof(lastKnownAddress));\n\n        try\n        {\n            return await ProbeAsync(lastKnownAddress, cancellationToken).ConfigureAwait(false);\n        }\n        catch (HttpRequestException)\n        {\n            // SSDP multicast does not cross routers. Search only the /24 of the\n            // last known address, and only the two VIDAA descriptor ports.\n        }\n\n        var octets = seed.GetAddressBytes();\n        using var deadline = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);\n        deadline.CancelAfter(TimeSpan.FromSeconds(8));\n        using var concurrency = new SemaphoreSlim(48, 48);\n        var probes = Enumerable.Range(1, 254)\n            .Select(host => ProbeSubnetCandidateAsync(\n                $\"{octets[0]}.{octets[1]}.{octets[2]}.{host}\", concurrency, deadline.Token))","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/mgth/LittleBigMouse/blob/7a42f01d47d99d223b8ee33ba4019af82adf1c48/LittleBigMouse.Plugins/LittleBigMouse.Plugin.Vcp.Avalonia/HisenseVidaa/HisenseVidaaDiscovery.cs#L35-L71","documentation":"FindAsync expects the caller-supplied lastKnownAddress to be a valid IPv4 address, which it parses with Ipv4Address.TryParse to seed the subnet scan. If parsing fails, it throws ArgumentException naming the lastKnownAddress parameter before any network activity.","triggerScenarios":"Calling FindAsync with a hostname, empty string, IPv6 address, or otherwise malformed lastKnownAddress that Ipv4Address.TryParse rejects.","commonSituations":"Saving a hostname from mDNS instead of an IP in app settings; stale or hand-edited config containing '192.168.1.' or 'projector.local'; empty field on first run.","solutions":["Pass a literal IPv4 address string (e.g. \"192.168.1.50\") as lastKnownAddress","Validate the address with Ipv4Address.TryParse (or IPAddress.TryParse) before calling FindAsync","Fix the stored setting that supplies the address","Resolve a hostname to an IPv4 via DNS first, then pass the resulting IP"],"exampleFix":"// before\nvar device = await discovery.FindAsync(settings.LastAddress, token);\n// after\nif (!Ipv4Address.TryParse(settings.LastAddress, out _))\n    throw new ArgumentException(\"Stored address must be an IPv4 address.\");\nvar device = await discovery.FindAsync(settings.LastAddress, token);","handlingStrategy":"validation","validationCode":"if (!Ipv4Address.TryParse(lastKnownAddress, out _))\n    throw new ArgumentException(\"Provide a valid IPv4 address.\", nameof(lastKnownAddress));","typeGuard":"bool IsIpv4(string s) => System.Net.IPAddress.TryParse(s, out var a) && a.AddressFamily == AddressFamily.InterNetwork;","tryCatchPattern":"try { var d = await discovery.FindAsync(addr, token); }\ncatch (ArgumentException ex) { showUser(ex.Message); }","preventionTips":["Store IPs, not hostnames, as lastKnownAddress","Validate settings input on save","Resolve hostnames to IPv4 before calling","Reject empty address fields before invoking discovery"],"tags":["validation","argument","ipv4","hisense-vidaa"],"backgroundTag":"invalid-argument-format","analyzedSha":"7a42f01d47d99d223b8ee33ba4019af82adf1c48","analyzedAt":"2026-09-16T00:35:00.514Z","contentChangedAt":"2026-09-16T00:35:00.514Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}