elsa-workflows/elsa-core · error · FaultException
NoHttpContext
NoHttpContext
Error message
The HTTP context was lost during workflow execution. This typically occurs when a workflow initiated from an HTTP endpoint is suspended and later resumed in a different execution context (e.g., background processing, virtual actor, or after a workflow transition). The original HTTP request context that expects a response is no longer available.
What it means
WriteHttpResponse writes a response body/status to the ASP.NET HTTP context captured when the workflow's HTTP endpoint received the request. If IHttpContextAccessor.HttpContext is null during ExecuteAsync, the activity throws a FaultException with code NoHttpContext, because there is no live response to write. This guards against workflows resuming after suspension in a non-HTTP execution context.
Solutions
- Write the HTTP response before any suspending activity; if asynchronous delivery is needed, respond with 202 Accepted early and push the final result via a callback/SignalR.
- Refactor so the final response is produced by a subsequent HttpEndpoint request (the client polls or a webhook triggers the completion response).
- Use workflow-correlated delivery mechanisms (e.g., HTTP bookmarks where the resume request itself carries the HTTP context) instead of assuming the original context survives.
Example fix
// before: HttpEndpoint -> Event(approval) -> WriteHttpResponse("done") // NoHttpContext on resume
// after: HttpEndpoint -> WriteHttpResponse("pending") -> Event(approval) -> notify via webhook/SignalR Defensive patterns
Strategy: validation
Validate before calling
// Guard before writing the response in the workflow
var hasHttpContext = httpContextAccessor.HttpContext is not null;
if (!hasHttpContext)
{
// fall back to non-HTTP delivery (store result, notify via SignalR/webhook)
} Try / catch
// Inspect the fault after resume
workflowDispatcher.OnFault((instance, fault) => {
if (fault.Code == HttpFaultCodes.NoHttpContext)
logger.LogWarning("Workflow {Id} attempted HTTP response without context; switch to callback pattern", instance.Id);
}); Prevention
- Write the HTTP response synchronously before any suspending activity.
- Use 202 Accepted + out-of-band result delivery for long-running flows.
- In distributed deployments, never assume the resuming node has the original request.
When it happens
Trigger: ExecuteAsync of WriteHttpResponse runs while httpContextAccessor.HttpContext is null — the workflow was suspended (bookmark, timer, task) after the HTTP request completed and resumed on a background worker, virtual actor, or different node without the original request context.
Common situations: HTTP-triggered workflow with an intermediate Delay or human-task approval, then attempting to send the final HTTP response; server restarts while the workflow was suspended; distributed deployments where the resuming instance never saw the original request.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- NoHttpContext
- RequestBodyTooLargeException (no message; thrown when HTTP…
- Content of type is not supported.
- AlterationFaultCodes.PlanNotFound
- No alterations found in the transient properties.
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/09d99d3cb162d72a.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.Http/Activities/WriteHttpResponse.cs:85
/// <summary>
/// The headers to return along with the response.
/// </summary>
[Input(
Description = "The headers to send along with the response.",
UIHint = InputUIHints.JsonEditor,
Category = "Advanced"
)]
public Input<HttpHeaders?> ResponseHeaders { get; set; } = new(new HttpHeaders());
/// <inheritdoc />
protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
{
var httpContextAccessor = context.GetRequiredService<IHttpContextAccessor>();
var httpContext = httpContextAccessor.HttpContext;
if (httpContext == null)
{
throw new FaultException(
HttpFaultCodes.NoHttpContext,
HttpFaultCategories.Http,
DefaultFaultTypes.System,
"The HTTP context was lost during workflow execution. This typically occurs when a workflow initiated from an HTTP endpoint is suspended and later resumed in a different execution context (e.g., background processing, virtual actor, or after a workflow transition). The original HTTP request context that expects a response is no longer available.");
}
await WriteResponseAsync(context, httpContext.Response);
}
private async Task WriteResponseAsync(ActivityExecutionContext context, HttpResponse response)
{
// Set status code.
var statusCode = StatusCode.GetOrDefault(context, () => HttpStatusCode.OK);
response.StatusCode = (int)statusCode;
// Add headers.
var headers = context.GetHeaders(ResponseHeaders);
foreach (var header in headers)View on GitHub (pinned to fe9217bdfa)