litedb-org/LiteDB · error · ArgumentOutOfRangeException

Method Round need 2 arguments when convert to BsonExpression

Error message

Method Round need 2 arguments when convert to BsonExpression

What it means

LiteDB's MathResolver only supports the two-argument overload of Math.Round (value + digits) which maps to ROUND(@0, @1). It throws ArgumentOutOfRangeException for the single-argument Math.Round(x) and the three-argument Math.Round(x, digits, MidpointRounding) because the BsonExpression ROUND function has no equivalents for those semantics.

Source

Thrown at LiteDB/Client/Mapper/Linq/TypeResolver/MathResolver.cs:23

using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using static LiteDB.Constants;

namespace LiteDB
{
    internal class MathResolver : ITypeResolver
    {
        public string ResolveMethod(MethodInfo method)
        {
            var qtParams = method.GetParameters().Length;

            switch (method.Name)
            {
                case "Abs": return "ABS(@0)";
                case "Pow": return "POW(@0, @1)";
                case "Round":
                    if (qtParams != 2) throw new ArgumentOutOfRangeException("Method Round need 2 arguments when convert to BsonExpression");
                    return "ROUND(@0, @1)";
            }

            return null;
        }

        public string ResolveMember(MemberInfo member) => null;
        public string ResolveCtor(ConstructorInfo ctor) => null;
    }
}

View on GitHub (pinned to f906a5f850)

Solutions

  1. Use the two-argument overload: Math.Round(x, 0) rounds to integer with 0 fractional digits.
  2. If you need MidpointRounding.AwayFromZero, round the value in memory before or after the query rather than in the LINQ expression.
  3. Pre-compute rounded values and store them as a separate field.

Example fix

// before
var q = col.Query().Select(x => Math.Round(x.Price)).ToList();
// after
var q = col.Query().Select(x => Math.Round(x.Price, 0)).ToList();
Defensive patterns

Strategy: validation

Validate before calling

// Always use the two-argument overload of Math.Round in LINQ expressions
// Math.Round(x, digits) — NOT Math.Round(x) or Math.Round(x, d, MidpointRounding.X)
var q = col.Query().Select(x => Math.Round(x.Price, 2));

Try / catch

try
{
    var q = col.Query().Select(x => Math.Round(x.Value, 2));
}
catch (ArgumentOutOfRangeException ex) when (ex.Message.Contains("Round"))
{
    // Use Math.Round(x, digits) with exactly 2 arguments
    throw;
}

Prevention

When it happens

Trigger: Using Math.Round(x) (banker's rounding to integer) or Math.Round(x, d, MidpointRounding.AwayFromZero) in a LINQ expression that LiteDB translates to BsonExpression.

Common situations: Rounding a salary or price field in a Where/Select. Using MidpointRounding.AwayFromZero expecting SQL-style rounding. Calling Math.Round(x) to round to the nearest integer.

Related errors


AI-assisted analysis of litedb-org/LiteDB@f906a5f850 (2026-08-13). Data as JSON: /api/errors/94faf42482b1ef2f. Report an issue: GitHub.