{"record":{"id":"731455b304702642","repo":"mgth/LittleBigMouse","slug":"the-probe-returned-an-invalid-delta-e-value","errorCode":null,"errorMessage":"The probe returned an invalid Delta E value.","messagePattern":"The probe returned an invalid Delta E value\\.","errorType":"exception","errorClass":"CalibrationMeasurementException","httpStatus":null,"severity":"error","filePath":"LittleBigMouse.Plugins/LittleBigMouse.Plugin.Vcp/Calibration/WhitePointOptimizer.cs","lineNumber":140,"sourceCode":"\n        return new(gains, deltaE, gains != original, reads);\n    }\n\n    static async Task<CachedMeasurement> MeasureAtGainsAsync(\n        ICalibrationHardware hardware,\n        CalibrationRgb gains,\n        TimeSpan settleDelay,\n        Dictionary<CalibrationRgb, double> cache,\n        CancellationToken cancellationToken)\n    {\n        if (cache.TryGetValue(gains, out var cached)) return new(cached, false);\n\n        await hardware.SetGainsAsync(gains, cancellationToken).ConfigureAwait(false);\n        if (settleDelay > TimeSpan.Zero)\n            await Task.Delay(settleDelay, cancellationToken).ConfigureAwait(false);\n        var measurement = await hardware.MeasureAsync(cancellationToken).ConfigureAwait(false);\n        if (!double.IsFinite(measurement.DeltaE))\n            throw new CalibrationMeasurementException(\"The probe returned an invalid Delta E value.\");\n        cache[gains] = measurement.DeltaE;\n        return new(measurement.DeltaE, true);\n    }\n\n    static bool CanMove(\n        CalibrationRgb gains,\n        IReadOnlyList<int> channels,\n        int count,\n        IReadOnlyList<uint> boundary,\n        bool down)\n    {\n        for (var i = 0; i < count; i++)\n        {\n            var value = gains.Channel(channels[i]);\n            if (down ? value <= boundary[i] : value >= boundary[i]) return false;\n        }\n        return true;\n    }","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/mgth/LittleBigMouse/blob/7a42f01d47d99d223b8ee33ba4019af82adf1c48/LittleBigMouse.Plugins/LittleBigMouse.Plugin.Vcp/Calibration/WhitePointOptimizer.cs#L122-L158","documentation":"WhitePointOptimizer.MeasureAtGainsAsync applies a gain setting, waits the settle delay, and reads the probe measurement. If measurement.DeltaE is not finite (NaN or Infinity), the value is useless for optimization, so the library throws CalibrationMeasurementException instead of caching or optimizing against garbage data.","triggerScenarios":"Calling MeasureAtGainsAsync (directly, or via TuneChannelAsync / the baseline and measured passes) when hardware.MeasureAsync returns a DeltaE of NaN or Infinity — e.g. the colorimeter lost its calibration, returned a failed reading, or measured in an invalid state.","commonSituations":"Probe unclipped or moved during settling; ambient light or a black screen producing a division-by-zero in the meter's firmware; a colorimeter driver returning sentinel values; USB hiccup producing an empty reading.","solutions":["Retry the measurement at the same gains after re-seating/stabilizing the probe on the panel","Verify the probe is connected, calibrated, and its driver/firmware reports valid readings outside this library","Increase settleDelay so the display and probe reach steady state before MeasureAsync","Catch CalibrationMeasurementException around optimization and abort/restart the calibration run"],"exampleFix":"// before\nvar result = await optimizer.OptimizeAsync(...); // throws on NaN DeltaE\n// after\ntry { var result = await optimizer.OptimizeAsync(...); }\ncatch (CalibrationMeasurementException ex)\n{\n    logger.LogWarning(ex, \"Probe returned invalid Delta E; recheck probe placement and retry.\");\n}","handlingStrategy":"try-catch","validationCode":"var m = await hardware.MeasureAsync(ct);\nif (!double.IsFinite(m.DeltaE))\n    throw new CalibrationMeasurementException(\"Probe returned invalid Delta E.\");","typeGuard":"static bool IsValidMeasurement(ProbeMeasurement m) => double.IsFinite(m.DeltaE);","tryCatchPattern":"try\n{\n    await optimizer.OptimizeAsync(...);\n}\ncatch (CalibrationMeasurementException ex)\n{\n    // abort calibration, prompt probe recheck, offer retry\n}","preventionTips":["Seat the probe firmly and keep it undisturbed during settle delays","Increase settleDelay for slow-refreshing displays","Verify probe calibration/driver health before starting optimization","Retry individual measurements before failing the whole run"],"tags":["calibration","hardware","colorimeter","invalid-measurement"],"backgroundTag":"unexpected-response-shape","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"}