dotnet/efcore · error · ArgumentException

The number argument cannot be a negative number.

Error message

The number argument cannot be a negative number.

What it means

Thrown by the PrecisionAttribute(int precision, int scale) constructor when the precision argument is negative. Precision (max digits) is meaningless below zero, so the constructor rejects it immediately. The error surfaces at attribute construction time, typically during model building or first use of the attribute.

Source

Thrown at src/EFCore.Abstractions/PrecisionAttribute.cs:26

///     For example, if the property is a <see cref="decimal" />
///     then this is the maximum number of digits.
/// </summary>
/// <remarks>
///     See <see href="https://aka.ms/efcore-docs-modeling">Modeling entity types and relationships</see> for more information and examples.
/// </remarks>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class PrecisionAttribute : Attribute
{
    /// <summary>
    ///     Initializes a new instance of the <see cref="PrecisionAttribute" /> class.
    /// </summary>
    /// <param name="precision">The precision of the property.</param>
    /// <param name="scale">The scale of the property.</param>
    public PrecisionAttribute(int precision, int scale)
    {
        if (precision < 0)
        {
            throw new ArgumentException(AbstractionsStrings.ArgumentIsNegativeNumber, nameof(precision));
        }

        if (scale < 0)
        {
            throw new ArgumentException(AbstractionsStrings.ArgumentIsNegativeNumber, nameof(scale));
        }

        Precision = precision;
        Scale = scale;
    }

    /// <summary>
    ///     Initializes a new instance of the <see cref="PrecisionAttribute" /> class.
    /// </summary>
    /// <param name="precision">The precision of the property.</param>
    public PrecisionAttribute(int precision)
    {
        if (precision < 0)

View on GitHub (pinned to dbf9771522)

Solutions

  1. Pass a non-negative precision value (0 or greater); for decimal columns a typical range is 1-38.
  2. If precision comes from external input, validate or clamp it to >= 0 before applying the attribute/constructing it.
  3. Use a sentinel-to-default mapping (e.g., -1 -> unset) outside the attribute, and only construct PrecisionAttribute with a valid non-negative number.

Example fix

// before
[Precision(-1, 2)]
public decimal Price { get; set; }

// after
[Precision(18, 2)]
public decimal Price { get; set; }
Defensive patterns

Strategy: validation

Validate before calling

if (precision < 0)
{
    throw new ArgumentOutOfRangeException(nameof(precision), "Precision must be non-negative.");
}
var attr = new PrecisionAttribute(precision, scale);

Type guard

static bool IsValidPrecision(int precision) => precision >= 0;

Prevention

When it happens

Trigger: Applying [Precision(precision, scale)] where precision is < 0, or constructing new PrecisionAttribute(-1, 2). Also triggered by code that computes precision from user/env input without clamping.

Common situations: Reading precision from a config file, environment variable, or database and passing a sentinel like -1 meaning 'unset'. Off-by-one or sign errors in computed precision values. Copying a precision literal from another column and editing it incorrectly.

Related errors


AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06). Data as JSON: /api/errors/f7573a44a59a9cde. Report an issue: GitHub.