{"record":{"id":"f9fd04198ac8e443","repo":"App-vNext/Polly","slug":"taskexecution-is-not-initialized","errorCode":null,"errorMessage":"TaskExecution is not initialized.","messagePattern":"TaskExecution is not initialized\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Polly.Core/Hedging/Controller/TaskExecution.cs","lineNumber":58,"sourceCode":"    }\n\n    /// <summary>\n    /// Gets the task that represents the execution of the hedged task.\n    /// </summary>\n    /// <remarks>\n    /// This property is not-null once the <see cref=\"TaskExecution{T}\"/> is initialized.\n    /// Awaiting this task will never throw as all exceptions are caught and stored\n    /// into <see cref=\"Outcome\"/> property.\n    /// </remarks>\n    public Task? ExecutionTaskSafe { get; private set; }\n\n    public Outcome<T> Outcome { get; private set; }\n\n    public bool IsHandled { get; private set; }\n\n    public bool IsAccepted { get; private set; }\n\n    public ResilienceContext Context => _activeContext ?? throw new InvalidOperationException(\"TaskExecution is not initialized.\");\n\n    public HedgedTaskType Type { get; set; }\n\n    public Action<TaskExecution<T>>? OnReset { get; set; }\n\n    public TimeSpan ExecutionTime => _timeProvider.GetElapsedTime(_startExecutionTimestamp, _stopExecutionTimestamp);\n\n    public int AttemptNumber { get; private set; }\n\n    public void AcceptOutcome()\n    {\n        if (ExecutionTaskSafe?.IsCompleted == true)\n        {\n            IsAccepted = true;\n        }\n        else\n        {\n            throw new InvalidOperationException(\"Unable to accept outcome for a task that is not completed.\");","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/App-vNext/Polly/blob/d0e46bdb1ee11ea50d0e4b6846d2633d6bc09bac/src/Polly.Core/Hedging/Controller/TaskExecution.cs#L40-L76","documentation":"TaskExecution<T>.Context throws InvalidOperationException when _activeContext is null, i.e. before InitializeAsync has run. TaskExecution is an internal hedging controller primitive that represents one hedged attempt; its Context is only valid between InitializeAsync and ResetAsync. Accessing Context outside that window violates the controller's lifecycle contract.","triggerScenarios":"Internal code reading the Context property before calling InitializeAsync, or after ResetAsync has cleared _activeContext. Practically surfaces only through Polly's hedging internals or a custom HedgingHandler.ActionGenerator that misuses the handed-off TaskExecution.","commonSituations":"A custom action generator that inspects taskExecution.Context inside its factory before the controller has initialized the attempt; a bug in a fork or in code reaching into internals via reflection; race where ResetAsync runs before a telemetry callback reads Context.","solutions":["Ensure InitializeAsync is awaited before any access to TaskExecution.Context; treat the object as invalid after ResetAsync.","If writing a custom HedgingHandler.ActionGenerator, only read Context from the TaskExecution you receive after the controller invokes your generator (it is initialized by then).","Avoid reflecting into or caching TaskExecution instances; let the HedgingResilienceStrategy own the lifecycle."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["TaskExecution is internal infrastructure; do not reflect into or cache it.","In a custom HedgingHandler.ActionGenerator, only read Context from the TaskExecution handed to you after invocation.","Treat TaskExecution as invalid after ResetAsync; never access Context across the reset boundary."],"tags":["hedging","internal","invalid-operation","lifecycle","polly-core"],"backgroundTag":null,"analyzedSha":"d0e46bdb1ee11ea50d0e4b6846d2633d6bc09bac","analyzedAt":"2026-08-13T16:36:01.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}