abpframework/abp · error · ArgumentException

Invalid background job name filter mode: {mode}

Error message

Invalid background job name filter mode: {mode}

What it means

Thrown by the BackgroundJobNameFilter constructor when the mode argument is not a defined BackgroundJobNameFilterMode enum value (checked via Enum.IsDefined). This catches corrupted/invalid enum values cast from integers or default uninitialized mode fields.

Source

Thrown at framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobNameFilter.cs:27

/// A worker is exactly one of: no filter (<see cref="None"/>), include-only (a dedicated worker) or
/// exclude-only (the default worker in a multi-worker setup) — the two can never be combined.
/// </summary>
public class BackgroundJobNameFilter
{
    /// <summary>
    /// A filter that matches every job name.
    /// </summary>
    public static BackgroundJobNameFilter None { get; } = new(BackgroundJobNameFilterMode.None);

    public BackgroundJobNameFilterMode Mode { get; }

    public IReadOnlyList<string> JobNames { get; }

    public BackgroundJobNameFilter(BackgroundJobNameFilterMode mode, IReadOnlyList<string>? jobNames = null)
    {
        if (!Enum.IsDefined(typeof(BackgroundJobNameFilterMode), mode))
        {
            throw new ArgumentException($"Invalid background job name filter mode: {mode}", nameof(mode));
        }

        var names = jobNames?.Where(x => !x.IsNullOrWhiteSpace()).Distinct(StringComparer.Ordinal).ToList() ?? new List<string>();

        if (mode == BackgroundJobNameFilterMode.None && names.Count > 0)
        {
            throw new ArgumentException("Job names must be empty when the filter mode is None.", nameof(jobNames));
        }

        if (mode != BackgroundJobNameFilterMode.None && names.Count == 0)
        {
            throw new ArgumentException("Job names cannot be empty when the filter mode is Include or Exclude.", nameof(jobNames));
        }

        Mode = mode;
        JobNames = names.AsReadOnly();
    }

View on GitHub (pinned to 7ed43b1931)

Solutions

  1. Pass only defined BackgroundJobNameFilterMode values (None, Include, Exclude).
  2. Validate the enum value with Enum.IsDefined before constructing the filter.
  3. Use the static factories Include(...) / Exclude(...) / None instead of the constructor to avoid bad casts.
  4. If deserializing, constrain/validate accepted values at the boundary.

Example fix

// before
var f = new BackgroundJobNameFilter((BackgroundJobNameFilterMode)42, names); // throws
// after
var f = BackgroundJobNameFilter.Include(names);
Defensive patterns

Strategy: type-guard

Validate before calling

if (!Enum.IsDefined(typeof(BackgroundJobNameFilterMode), mode))
{
    /* reject/normalize before constructing BackgroundJobNameFilter */
}

Type guard

static bool IsValidMode(BackgroundJobNameFilterMode m) => Enum.IsDefined(typeof(BackgroundJobNameFilterMode), m);

Try / catch

try { var f = new BackgroundJobNameFilter(mode, names); }
catch (ArgumentException ex) when (ex.Message.Contains("Invalid background job name filter mode"))
{ /* coerce to a valid mode or reject input */ }

Prevention

When it happens

Trigger: Constructing new BackgroundJobNameFilter((BackgroundJobNameFilterMode)999, ...) with an out-of-range int cast to the enum, or passing an uninitialized (defaulted) mode that isn't a valid member.

Common situations: Casting an arbitrary integer to the enum; deserializing a mode value that doesn't match any defined member; uninitialized struct field defaulting to an invalid value; future enum member removed but caller still sends the old integer.

Related errors


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