{"record":{"id":"b9210877295a7477","repo":"MaterialDesignInXAML/MaterialDesignInXamlToolkit","slug":"invalid-hsb-values","errorCode":null,"errorMessage":"Invalid HSB values","messagePattern":"Invalid HSB values","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/MaterialDesignColors.Wpf/ColorManipulation/HsbExtensions.cs","lineNumber":37,"sourceCode":"        while (h < 0) h += 360;\n\n        h /= 60;\n\n        int i = (int)Math.Floor(h);\n        double f = h - i;\n        double p = b * (1 - s);\n        double q = b * (1 - s * f);\n        double t = b * (1 - s * (1 - f));\n\n        return i switch\n        {\n            0 => Color.FromRgb((byte)b, (byte)t, (byte)p),\n            1 => Color.FromRgb((byte)q, (byte)b, (byte)p),\n            2 => Color.FromRgb((byte)p, (byte)b, (byte)t),\n            3 => Color.FromRgb((byte)p, (byte)q, (byte)b),\n            4 => Color.FromRgb((byte)t, (byte)p, (byte)b),\n            5 => Color.FromRgb((byte)b, (byte)p, (byte)q),\n            _ => throw new InvalidOperationException(\"Invalid HSB values\"),\n        };\n    }\n\n    public static Hsb ToHsb(this Color color)\n    {\n        double r = color.R;\n        double g = color.G;\n        double b = color.B;\n\n        r /= 255;\n        g /= 255;\n        b /= 255;\n\n        double[] rgb = [r, g, b];\n        double max = rgb.Max();\n        double min = rgb.Min();\n        double v = max;\n        double h = max;","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit/blob/98edec3a0b96ef272c587b14bcd67ef5f928a7ed/src/MaterialDesignColors.Wpf/ColorManipulation/HsbExtensions.cs#L19-L55","documentation":"`HsbExtensions.ToColor` converts an HSB color to a WPF `Color` via a six-armed switch on the sector index `i` (0-5). The default arm `throw new InvalidOperationException(\"Invalid HSB values\")` fires when `i` is outside 0-5. After normalizing hue into [0,360) and dividing by 60, `i = (int)Math.Floor(h)` should be 0-5, but a hue of exactly `360.0` slips past the epsilon-tolerant `h.IsCloseTo(360)` guard (0 < double.Epsilon is false) and yields `i = 6`.","triggerScenarios":"Calling `ToColor` on an `Hsb` whose `Hue` is exactly `360.0` (or any value the normalization leaves at/above 360); constructing an Hsb from code/round-tripping a color whose computed hue lands exactly on the 360 boundary; NaN or infinity in saturation/brightness interacting with the floor.","commonSituations":"Red colors whose `ToHsb` round-trip produces hue 0/360 boundary values; feeding user-provided HSB triples from a color picker; using a hue slider that allows 360 as its maximum.","solutions":["Normalize hue to [0,360) yourself before calling ToColor: `hue %= 360; if (hue < 0) hue += 360;` and avoid passing exactly 360.","Upgrade the library / patch `ToColor` so the 360 guard is inclusive (e.g. `if (h >= 360) h = 0;` after the wrap loops) and/or extend the switch to handle `i == 6` as sector 0.","Validate inputs: reject NaN/infinity and clamp hue to [0,360).","If consuming the library as-is, wrap the call and on failure retry with `hue = 0`."],"exampleFix":"// before\nvar c = new Hsb(360.0, 1.0, 1.0).ToColor(); // throws Invalid HSB values\n\n// after (caller clamp)\ndouble hue = 360.0 % 360;\nif (hue < 0) hue += 360;\nvar c = new Hsb(hue, 1.0, 1.0).ToColor();","handlingStrategy":"validation","validationCode":"double SafeHue(double hue)\n{\n    if (double.IsNaN(hue) || double.IsInfinity(hue)) hue = 0;\n    hue %= 360;\n    if (hue < 0) hue += 360;\n    return hue; // strictly [0,360)\n}\nvar c = new Hsb(SafeHue(inputHue), sat, bright).ToColor();","typeGuard":"static bool IsValidHsb(in Hsb h) =>\n    !double.IsNaN(h.Hue) && !double.IsInfinity(h.Hue) &&\n    h.Hue >= 0 && h.Hue < 360 &&\n    h.Saturation >= 0 && h.Saturation <= 1 &&\n    h.Brightness >= 0 && h.Brightness <= 1;","tryCatchPattern":"try { color = hsb.ToColor(); }\ncatch (InvalidOperationException)\n{\n    // edge: hue landed exactly on 360; retry wrapped\n    color = new Hsb(0, hsb.Saturation, hsb.Brightness).ToColor();\n}","preventionTips":["Always normalize hue into [0,360) (open upper bound) before calling ToColor.","Reject NaN/Infinity in HSB inputs.","Patch/upgrade the library so the 360 guard and switch are inclusive."],"tags":["wpf","color","hsb","math","edge-case","data-conversion"],"backgroundTag":null,"analyzedSha":"98edec3a0b96ef272c587b14bcd67ef5f928a7ed","analyzedAt":"2026-08-13T14:31:19.111Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}