abpframework/abp · error · ArgumentException

{parameterName} is null!

Error message

{parameterName} is null!

What it means

Thrown by Check.NotDefaultOrNull<T> when a nullable value type T? (where T : struct) argument is null. Unlike NotNull, this overload is for nullable structs and reports the first of two checks — null vs default(T). It is an ArgumentException carrying parameterName.

Source

Thrown at framework/src/Volo.Abp.Core/Volo/Abp/Check.cs:350

        decimal minimumValue,
        decimal maximumValue = decimal.MaxValue)
    {
        if (value < minimumValue || value > maximumValue)
        {
            throw new ArgumentException($"{parameterName} is out of range min: {minimumValue} - max: {maximumValue}");
        }

        return value;
    }

    public static T NotDefaultOrNull<T>(
        [System.Diagnostics.CodeAnalysis.NotNull] T? value,
        [InvokerParameterName][NotNull] string parameterName)
        where T : struct
    {
        if (value == null)
        {
            throw new ArgumentException($"{parameterName} is null!", parameterName);
        }

        if (value.Value.Equals(default(T)))
        {
            throw new ArgumentException($"{parameterName} has a default value!", parameterName);
        }

        return value.Value;
    }
}

View on GitHub (pinned to 7ed43b1931)

Solutions

  1. Supply a concrete value instead of null before calling NotDefaultOrNull.
  2. If null is legitimately allowed, do not use NotDefaultOrNull — use plain null-tolerant logic or Check.NotNull on a reference.
  3. Initialize the nullable to a real default (Guid.NewGuid(), DateTime.UtcNow) at construction.
  4. Validate at the API boundary with [Required] so the caller is told which field is missing.

Example fix

// before
var tenantId = Check.NotDefaultOrNull(input.TenantId, nameof(input.TenantId));

// after
if (input.TenantId is null)
{
    return BadRequest("TenantId is required.");
}
var tenantId = Check.NotDefaultOrNull(input.TenantId, nameof(input.TenantId));
Defensive patterns

Strategy: validation

Validate before calling

static bool HasValue<T>(T? value) where T : struct => value is not null;

if (!HasValue(input.TenantId)) return BadRequest("TenantId is required");
var tenantId = Check.NotDefaultOrNull(input.TenantId, nameof(input.TenantId));

Type guard

static bool IsSet<T>(T? value) where T : struct => value.HasValue;
// usage: if (IsSet(maybeGuid)) { /* safe to call NotDefaultOrNull next */ }

Try / catch

try
{
    var id = Check.NotDefaultOrNull(input.Id, nameof(input.Id));
}
catch (ArgumentException ex) when (ex.ParamName == nameof(input.Id))
{
    return NotFound("Id not supplied");
}

Prevention

When it happens

Trigger: Calling Check.NotDefaultOrNull(maybeStruct, nameof(maybeStruct)) where maybeStruct (e.g. Guid?, int?, DateTime?) is null.

Common situations: An optional identifier (Guid? tenantId) that was never set, a DTO property not supplied by the client, or a value read from a nullable DB column that came back DBNull.

Related errors


AI-assisted analysis of abpframework/abp@7ed43b1931 (2026-08-13). Data as JSON: /api/errors/0ba9bd3d26a56127. Report an issue: GitHub.