App-vNext/Polly · error · ArgumentNullException
Value cannot be null. (Parameter 'context')
Error message
Value cannot be null. (Parameter 'context')
What it means
Thrown by Policy.Execute(Action<Context,CancellationToken>, Context, CancellationToken) when the context argument is null. The context carries per-execution metadata and policy wrap keys through the pipeline, so Polly refuses to run without it. The guard sits before SetPolicyContext so that context bookkeeping never dereferences null.
Solutions
- Construct and pass a new Context() (or Context with a correlation key) instead of null: policy.Execute(action, new Context(), ct).
- If the context arrives from an optional parameter, default it to a fresh Context in the method signature.
- Add a null check on the context at the call site before invoking Execute.
- Enable nullable reference types so the compiler flags nullable Context arguments at the call site.
Example fix
// before Context ctx = GetContextMaybeNull(); policy.Execute(action, ctx, ct); // after Context ctx = GetContextMaybeNull() ?? new Context(); policy.Execute(action, ctx, ct);
Defensive patterns
Strategy: validation
Validate before calling
Context ctx = providedContext ?? new Context(); policy.Execute(action, ctx, cancellationToken);
Type guard
static bool IsContext(object o) => o is Context; // or guard: if (providedContext is not Context) return;
Prevention
- Default optional Context parameters to new Context() rather than null.
- Treat Context as non-nullable in your API surface; enable NRTs.
- Audit context-producing helpers to ensure they never return null.
When it happens
Trigger: Invoking policy.Execute(action, null, cancellationToken) on a non-generic Policy where the second argument is a null Context reference. Any synchronous Execute overload that requires an explicit Context hits this same guard shape.
Common situations: Passing a Context obtained from a nullable field or optional parameter without checking it; migrating from a context-free Execute overload and forgetting to construct a Context; DI/proxy code that forwards a possibly-null context.
Related errors
- Value cannot be null. (Parameter 'context')
- onRetry
- sleepDurationProvider
- Value cannot be null. (Parameter 'action')
- Value cannot be null. (Parameter 'action')
AI-assisted analysis of App-vNext/Polly@d0e46bdb1e (2026-08-13).
Data as JSON: /api/errors/31b872dc9a2e1dc8.
Report an issue: GitHub.
Appendix: source
Thrown at src/Polly/Policy.ExecuteOverloads.cs:64
/// <param name="contextData">Arbitrary data that is passed to the exception policy.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="contextData"/> is <see langword="null"/>.</exception>
[DebuggerStepThrough]
public void Execute(Action<Context, CancellationToken> action, IDictionary<string, object> contextData, CancellationToken cancellationToken) =>
Execute(action, new Context(contextData), cancellationToken);
/// <summary>
/// Executes the specified action within the policy.
/// </summary>
/// <param name="action">The action to perform.</param>
/// <param name="context">Context data that is passed to the exception policy.</param>
/// <param name="cancellationToken">The cancellation token.</param>
[DebuggerStepThrough]
public void Execute(Action<Context, CancellationToken> action, Context context, CancellationToken cancellationToken)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
SetPolicyContext(context, out string priorPolicyWrapKey, out string priorPolicyKey);
try
{
Implementation(action, context, cancellationToken);
}
finally
{
RestorePolicyContext(context, priorPolicyWrapKey, priorPolicyKey);
}
}
#region Overloads method-generic in TResult
/// <summary>
/// Executes the specified action within the policy and returns the Result.View on GitHub (pinned to d0e46bdb1e)