{"record":{"id":"6c3bcbd8cfc0c417","repo":"nopSolutions/nopCommerce","slug":"exchange-ratio-not-set-for-dimension-targetmeasu","errorCode":null,"errorMessage":"Exchange ratio not set for dimension [{targetMeasureDimension.Name}]","messagePattern":"Exchange ratio not set for dimension \\[(.+?)\\]","errorType":"exception","errorClass":"NopException","httpStatus":null,"severity":"error","filePath":"src/Libraries/Nop.Services/Directory/MeasureService.cs","lineNumber":174,"sourceCode":"    /// <param name=\"value\">Value to convert</param>\r\n    /// <param name=\"targetMeasureDimension\">Target dimension</param>\r\n    /// <returns>\r\n    /// A task that represents the asynchronous operation\r\n    /// The task result contains the converted value\r\n    /// </returns>\r\n    public virtual async Task<decimal> ConvertFromPrimaryMeasureDimensionAsync(decimal value,\r\n        MeasureDimension targetMeasureDimension)\r\n    {\r\n        ArgumentNullException.ThrowIfNull(targetMeasureDimension);\r\n\r\n        var result = value;\r\n        var baseDimensionIn = await GetMeasureDimensionByIdAsync(_measureSettings.BaseDimensionId);\r\n        if (result == decimal.Zero || targetMeasureDimension.Id == baseDimensionIn.Id)\r\n            return result;\r\n\r\n        var exchangeRatio = targetMeasureDimension.Ratio;\r\n        if (exchangeRatio == decimal.Zero)\r\n            throw new NopException($\"Exchange ratio not set for dimension [{targetMeasureDimension.Name}]\");\r\n        result *= exchangeRatio;\r\n\r\n        return result;\r\n    }\r\n\r\n    /// <summary>\r\n    /// Converts to primary measure dimension\r\n    /// </summary>\r\n    /// <param name=\"value\">Value to convert</param>\r\n    /// <param name=\"sourceMeasureDimension\">Source dimension</param>\r\n    /// <returns>\r\n    /// A task that represents the asynchronous operation\r\n    /// The task result contains the converted value\r\n    /// </returns>\r\n    public virtual async Task<decimal> ConvertToPrimaryMeasureDimensionAsync(decimal value,\r\n        MeasureDimension sourceMeasureDimension)\r\n    {\r\n        ArgumentNullException.ThrowIfNull(sourceMeasureDimension);\r","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/nopSolutions/nopCommerce/blob/64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2/src/Libraries/Nop.Services/Directory/MeasureService.cs#L156-L192","documentation":"Thrown by ConvertFromPrimaryMeasureDimensionAsync as a NopException when targetMeasureDimension.Ratio equals decimal.Zero. Dimension conversion multiplies by the dimension's Ratio relative to the base dimension; a zero ratio would zero the result, so the guard rejects it. Also note GetMeasureDimensionByIdAsync(BaseDimensionId) is dereferenced without a null check — a missing base dimension would NullReferenceException before this line.","triggerScenarios":"Calling ConvertFromPrimaryMeasureDimensionAsync(value, dimension) where dimension.Rate/Ratio is 0 and the dimension differs from the configured base dimension. Triggers on any non-zero value being converted to a ratio-less dimension.","commonSituations":"A measure dimension (e.g., a custom unit) was added but its Ratio to the base dimension was never set; admin reset ratios; import wrote Ratio=0; base dimension misconfigured.","solutions":["Set a non-zero Ratio for the target measure dimension in Admin > Configuration > Measures.","Ensure MeasureSettings.BaseDimensionId points to a valid dimension (avoid the latent NRE on baseDimensionIn.Id).","Validate dimension.Ratio > 0 before calling the conversion."],"exampleFix":"// before\nvar value = await _measureService.ConvertFromPrimaryMeasureDimensionAsync(qty, dimension);\n\n// after\nif (dimension.Ratio == decimal.Zero)\n    throw new InvalidOperationException($\"Dimension '{dimension.Name}' has no ratio set.\");\nvar value = await _measureService.ConvertFromPrimaryMeasureDimensionAsync(qty, dimension);","handlingStrategy":"validation","validationCode":"if (targetMeasureDimension.Ratio == decimal.Zero)\n    throw new InvalidOperationException($\"Dimension '{targetMeasureDimension.Name}' has no ratio.\");","typeGuard":"static bool HasRatio(MeasureDimension d) => d is not null && d.Ratio != decimal.Zero;","tryCatchPattern":"try { await _measureService.ConvertFromPrimaryMeasureDimensionAsync(value, dim); }\ncatch (NopException ex) when (ex.Message.Contains(\"Exchange ratio not set\"))\n{ _logger.LogWarning(ex, \"Missing dimension ratio; skipping conversion.\"); }","preventionTips":["Set a non-zero Ratio for each measure dimension relative to the base.","Verify MeasureSettings.BaseDimensionId resolves to an existing dimension (avoids a latent NRE).","Validate Ratio > 0 before invoking conversions."],"tags":["measure","dimension","configuration","data"],"backgroundTag":null,"analyzedSha":"64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2","analyzedAt":"2026-08-13T21:19:38.062Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}