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 AsyncNoOpPolicy (non-generic).ImplementationAsync when the action delegate is null. NoOp passes the delegate straight through to NoOpEngine, so a null action cannot be invoked. The guard fires when the policy's Execute path is entered with a null func.
Source
Thrown at src/Polly/NoOp/AsyncNoOpPolicy.cs:20
namespace Polly.NoOp;
/// <summary>
/// A noop policy that can be applied to asynchronous delegates.
/// </summary>
public class AsyncNoOpPolicy : AsyncPolicy, INoOpPolicy
{
internal AsyncNoOpPolicy()
{
}
/// <inheritdoc/>
[DebuggerStepThrough]
protected override Task<TResult> ImplementationAsync<TResult>(Func<Context, CancellationToken, Task<TResult>> action, Context context, CancellationToken cancellationToken,
bool continueOnCapturedContext)
{
if (action is null)
{
throw new ArgumentNullException(nameof(action));
}
return NoOpEngine.ImplementationAsync(action, context, cancellationToken);
}
}
/// <summary>
/// A noop policy that can be applied to asynchronous delegates returning a value of type <typeparamref name="TResult"/>.
/// </summary>
/// <typeparam name="TResult">The type of the result.</typeparam>
public class AsyncNoOpPolicy<TResult> : AsyncPolicy<TResult>, INoOpPolicy<TResult>
{
internal AsyncNoOpPolicy()
{
}
/// <inheritdoc/>
[DebuggerStepThrough]View on GitHub (pinned to d0e46bdb1e)
Solutions
- Pass a non-null action delegate to ExecuteAsync.
- Guard the delegate before calling: if (action is not null) await policy.ExecuteAsync(action).
- Check DI registrations resolve a real delegate, not null.
Example fix
// before Func<CancellationToken, Task<int>> action = GetAction(); // may be null var result = await noOpPolicy.ExecuteAsync(action, ct); // after var action = GetAction() ?? (_ => Task.FromResult(0)); var result = await noOpPolicy.ExecuteAsync(action, ct);
Defensive patterns
Strategy: validation
Validate before calling
if (action is null) throw new ArgumentNullException(nameof(action)); await Policy.NoOpAsync().ExecuteAsync(action, ctx, ct);
Type guard
static Func<Context, CancellationToken, Task<T>> EnsureAction<T>(Func<Context, CancellationToken, Task<T>> a) => a ?? ((_, _) => Task.FromResult<T>(default));
Try / catch
try { await noOpPolicy.ExecuteAsync(action, ct); } catch (ArgumentNullException ex) when (ex.ParamName == "action") { /* supply delegate */ throw; } Prevention
- Validate delegates from DI/factories are non-null before executing.
- Coalesce with a default-returning delegate when null is plausible.
- Add a unit test executing NoOp with a real delegate.
When it happens
Trigger: Calling policy.ExecuteAsync(null) or passing a null Func<Context, CancellationToken, Task<TResult>> into an AsyncNoOpPolicy obtained via Policy.NoOpAsync().
Common situations: A null delegate resolved from DI/optional config; refactor that changed the delegate signature leaving a null reference; tests asserting no-op behavior but forgetting to supply a delegate.
Related errors
- Value cannot be null. (Parameter 'action')
- Value cannot be null. (Parameter 'onFallback')
- Value cannot be null. (Parameter 'fallbackAction')
- Value must be greater than zero.
- Value must be less than or equal to one.
AI-assisted analysis of App-vNext/Polly@d0e46bdb1e (2026-08-13).
Data as JSON: /api/errors/2f096bf505b20f14.
Report an issue: GitHub.