App-vNext/Polly · error · ArgumentNullException

Value cannot be null. (Parameter 'action')

Error message

Value cannot be null. (Parameter 'action')

What it means

ArgumentNullException thrown by the synchronous NoOpPolicy.Implementation when the action delegate is null. NoOp invokes the delegate directly via NoOpEngine.Implementation, so a null func is rejected at the Execute boundary with parameter name 'action'.

Source

Thrown at src/Polly/NoOp/NoOpPolicy.cs:19

#nullable enable
namespace Polly.NoOp;

/// <summary>
/// A no op policy that can be applied to delegates.
/// </summary>
public class NoOpPolicy : Policy, INoOpPolicy
{
    internal NoOpPolicy()
    {
    }

    /// <inheritdoc/>
    [DebuggerStepThrough]
    protected override TResult Implementation<TResult>(Func<Context, CancellationToken, TResult> action, Context context, CancellationToken cancellationToken)
    {
        if (action is null)
        {
            throw new ArgumentNullException(nameof(action));
        }

        return NoOpEngine.Implementation(action, context, cancellationToken);
    }
}

/// <summary>
/// A no op policy that can be applied to delegates returning a value of type <typeparamref name="TResult" />.
/// </summary>
/// <typeparam name="TResult">The type of return values this policy will handle.</typeparam>
public class NoOpPolicy<TResult> : Policy<TResult>, INoOpPolicy<TResult>
{
    internal NoOpPolicy()
    {
    }

    /// <inheritdoc/>
    [DebuggerStepThrough]

View on GitHub (pinned to d0e46bdb1e)

Solutions

  1. Pass a non-null synchronous delegate to Execute.
  2. Coalesce the delegate: action ?? ((_, _) => default).
  3. Confirm the DI/factory registration returns a concrete delegate.

Example fix

// before
var policy = Policy.NoOp();
var v = policy.Execute(_action /* null */, ct);

// after
var policy = Policy.NoOp();
Func<Context, CancellationToken, int> action = _action ?? ((_, _) => 0);
var v = policy.Execute(action, ct);
Defensive patterns

Strategy: validation

Validate before calling

if (action is null) throw new ArgumentNullException(nameof(action));
var v = Policy.NoOp().Execute(action, ctx, ct);

Type guard

static Func<Context, CancellationToken, T> EnsureAction<T>(Func<Context, CancellationToken, T> a) => a ?? ((_, _) => default);

Try / catch

try { return noOpPolicy.Execute(action, ct); } catch (ArgumentNullException ex) when (ex.ParamName == "action") { /* supply delegate */ throw; }

Prevention

When it happens

Trigger: Calling Policy.NoOp().Execute(null) or passing a null Func<Context, CancellationToken, TResult>.

Common situations: Null delegate from a factory/DI; refactor removing the action without updating the call site; test scaffolding that left the action unset.

Related errors


AI-assisted analysis of App-vNext/Polly@d0e46bdb1e (2026-08-13). Data as JSON: /api/errors/64c8f46c47761ccb. Report an issue: GitHub.