{"record":{"id":"70a9ffcb498d2d12","repo":"App-vNext/Polly","slug":"you-have-executed-the-generic-execute-tresult-me","errorCode":null,"errorMessage":"You have executed the generic .Execute<TResult> method on a non-generic FallbackPolicy.  A non-generic FallbackPolicy only defines a fallback action which returns void; it can never return a substitute TResult value.  To use FallbackPolicy to provide fallback TResult values you must define a generic fallback policy FallbackPolicy<TResult>.  For example, define the policy as Policy<TResult>.Handle<Whatever>.Fallback<TResult>(/* some TResult value or Func<..., TResult> */);","messagePattern":"You have executed the generic \\.Execute<TResult> method on a non-generic FallbackPolicy\\.  A non-generic FallbackPolicy only defines a fallback action which returns void; it can never return a substitute TResult value\\.  To use FallbackPolicy to provide fallback TResult values you must define a generic fallback policy FallbackPolicy<TResult>\\.  For example, define the policy as Policy<TResult>\\.Handle<Whatever>\\.Fallback<TResult>\\(/\\* some TResult value or Func<\\.\\.\\., TResult> \\*/\\);","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Polly/Fallback/AsyncFallbackPolicy.cs","lineNumber":49,"sourceCode":"                await action(ctx, ct).ConfigureAwait(continueOnCapturedContext);\n                return EmptyStruct.Instance;\n            },\n            context,\n            ExceptionPredicates,\n            ResultPredicates<EmptyStruct>.None,\n            (outcome, ctx) => _onFallbackAsync(outcome.Exception, ctx),\n            async (outcome, ctx, ct) =>\n            {\n                await _fallbackAction(outcome.Exception, ctx, ct).ConfigureAwait(continueOnCapturedContext);\n                return EmptyStruct.Instance;\n            },\n            continueOnCapturedContext,\n            cancellationToken);\n\n    /// <inheritdoc/>\n    protected override Task<TResult> ImplementationAsync<TResult>(Func<Context, CancellationToken, Task<TResult>> action, Context context, CancellationToken cancellationToken,\n        bool continueOnCapturedContext) =>\n        throw new InvalidOperationException($\"You have executed the generic .Execute<{nameof(TResult)}> method on a non-generic {nameof(FallbackPolicy)}.  \" +\n            $\"A non-generic {nameof(FallbackPolicy)} only defines a fallback action which returns void; it can never return a substitute {nameof(TResult)} value.  \" +\n            $\"To use {nameof(FallbackPolicy)} to provide fallback {nameof(TResult)} values you must define a generic fallback policy {nameof(FallbackPolicy)}<{nameof(TResult)}>.  \" +\n            $\"For example, define the policy as Policy<{nameof(TResult)}>.Handle<Whatever>.Fallback<{nameof(TResult)}>(/* some {nameof(TResult)} value or Func<..., {nameof(TResult)}> */);\");\n}\n\n/// <summary>\n/// A fallback policy that can be applied to delegates.\n/// </summary>\n/// <typeparam name=\"TResult\">The return type of delegates which may be executed through the policy.</typeparam>\npublic class AsyncFallbackPolicy<TResult> : AsyncPolicy<TResult>, IFallbackPolicy<TResult>\n{\n    private readonly Func<DelegateResult<TResult>, Context, Task> _onFallbackAsync;\n    private readonly Func<DelegateResult<TResult>, Context, CancellationToken, Task<TResult>> _fallbackAction;\n\n    internal AsyncFallbackPolicy(\n        PolicyBuilder<TResult> policyBuilder,\n        Func<DelegateResult<TResult>, Context, Task> onFallbackAsync,\n        Func<DelegateResult<TResult>, Context, CancellationToken, Task<TResult>> fallbackAction)","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/App-vNext/Polly/blob/d0e46bdb1ee11ea50d0e4b6846d2633d6bc09bac/src/Polly/Fallback/AsyncFallbackPolicy.cs#L31-L67","documentation":"Thrown when code calls the generic Execute<TResult>/ExecuteAsync<TResult> path on a NON-generic AsyncFallbackPolicy. A non-generic FallbackPolicy (Policy.Handle<...>.Fallback(...)) only defines a void fallback action; it cannot synthesize a substitute TResult, so the framework rejects the call with InvalidOperationException at execution time. To return fallback values you must build a generic FallbackPolicy<TResult> via Policy<TResult>.Handle<...>.Fallback<TResult>(...).","triggerScenarios":"Building the policy as Policy.Handle<X>().Fallback(...) (non-generic) and then calling ExecuteAsync<TResult>(...) or Execute<TResult>(...) on it, expecting it to yield a typed fallback value.","commonSituations":"Refactoring a void delegate policy into one that returns results but forgetting to switch Policy to Policy<TResult> and to the generic Fallback overload; copy-paste from a void tutorial into a value-returning handler.","solutions":["Define the policy generically: Policy<TResult>.Handle<Whatever>().Fallback<TResult>(fallbackValue or fallbackAction, onFallback).","Match the Execute call's TResult to the policy's TResult; use a non-generic Execute only with a non-generic FallbackPolicy.","If you truly want a void fallback, keep using non-generic Execute (not Execute<TResult>)."],"exampleFix":"// before\nvar policy = Policy\n    .Handle<HttpRequestException>()\n    .FallbackAsync(async (ex, ctx, ct) => { /* void fallback */ });\nvar value = await policy.ExecuteAsync<int>(ct => GetValueAsync(ct), ct); // throws\n\n// after\nvar policy = Policy<int>\n    .Handle<HttpRequestException>()\n    .FallbackAsync(fallbackValue: 0, onFallbackAsync: (outcome, ctx) => Task.CompletedTask);\nvar value = await policy.ExecuteAsync(ct => GetValueAsync(ct), ct);","handlingStrategy":"type-guard","validationCode":"// choose the policy arity at compile time to match the result\nvar policy = Policy<int>.Handle<HttpRequestException>()\n    .FallbackAsync(fallbackValue: 0, onFallbackAsync: (o, ctx) => Task.CompletedTask);\nvar v = await policy.ExecuteAsync(ct => GetAsync(ct), ct);","typeGuard":"// structural check before executing\nstatic bool IsResultFallbackPolicy(object p) => p is IFallbackPolicy<int>;","tryCatchPattern":"try { return await policy.ExecuteAsync<int>(action, ct); } catch (InvalidOperationException ex) when (ex.Message.Contains(\"non-generic FallbackPolicy\")) { log.PolicyArityMismatch(ex); throw; }","preventionTips":["Always declare the policy variable with the matching generic arity (Policy<TResult>, not Policy).","Build fallback-value policies with Policy<TResult>.Handle<...>().Fallback<TResult>(...).","Keep a unit test that executes the policy through ExecuteAsync<TResult> to catch arity mismatches early."],"tags":["fallback","generics","type-mismatch","csharp","async","legacy-api"],"backgroundTag":null,"analyzedSha":"d0e46bdb1ee11ea50d0e4b6846d2633d6bc09bac","analyzedAt":"2026-08-13T16:36:01.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}