OrchardCMS/OrchardCore · error · InvalidOperationException
An implementation of 'LiquidTemplateContext' is required
Error message
An implementation of 'LiquidTemplateContext' is required
What it means
The `http_request` Liquid value obtains the current HttpRequest through LiquidTemplateContext.Services -> IHttpContextAccessor -> HttpContext.Request. Because the context must expose services, the same cast guard applies: a plain TemplateContext triggers this InvalidOperationException instead of a NullReference deeper in the pipeline.
Solutions
- Render with LiquidTemplateContext so `Services` is available to resolve IHttpContextAccessor.
- Use ILiquidTemplateManager or the Liquid view engine for all template rendering in Orchard.
- Pass the needed request data into the template Model explicitly if rendering outside an HTTP scope.
Example fix
// before
var context = new TemplateContext { Model = model };
var html = await template.RenderAsync(context);
// after
var context = new LiquidTemplateContext(sp, memberAccessor) { Model = model };
var html = await template.RenderAsync(context); Defensive patterns
Strategy: type-guard
Validate before calling
if (context is not LiquidTemplateContext) throw new InvalidOperationException("request value requires a LiquidTemplateContext"); Type guard
bool IsLiquidContext(TemplateContext ctx) => ctx is LiquidTemplateContext;
Try / catch
try { var html = await template.RenderAsync(ctx); } catch (InvalidOperationException ex) when (ex.Message.Contains("LiquidTemplateContext")) { /* rebuild context via ILiquidTemplateManager */ } Prevention
- Render request-dependent templates only within the HTTP pipeline.
- Pass request data explicitly via the Model when rendering in background jobs.
- Use a single shared rendering helper that always supplies LiquidTemplateContext.
When it happens
Trigger: Evaluating `{{ request }}` or request members (query, form, headers, path) in a template rendered with a base TemplateContext rather than LiquidTemplateContext.
Common situations: Custom batch/email template renderers that build contexts manually; unit tests of Liquid templates with `new TemplateContext()`; direct FluidValue member calls outside the view pipeline.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- An implementation of 'LiquidTemplateContext' is required
- An implementation of 'LiquidTemplateContext' is required
- An implementation of 'LiquidTemplateContext' is required
- Cannot override href with other properties
- Format of the link cannot be determined based on the…
AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13).
Data as JSON: /api/errors/0d773b6346c572ab.
Report an issue: GitHub.
Appendix: source
Thrown at src/OrchardCore/OrchardCore.DisplayManagement.Liquid/Values/HttpRequestValue.cs:75
nameof(HttpRequest.Host) => new StringValue(request.Host.Value),
nameof(HttpRequest.IsHttps) => BooleanValue.Create(request.IsHttps),
nameof(HttpRequest.Scheme) => new StringValue(request.Scheme),
nameof(HttpRequest.Method) => new StringValue(request.Method),
nameof(HttpRequest.RouteValues) => new ObjectValue(new RouteValueDictionaryWrapper(request.RouteValues)),
// Provides correct escaping to reconstruct a request or redirect URI.
"UriHost" => new StringValue(request.Host.ToUriComponent(), encode: false),
"UriPath" => new StringValue(request.Path.ToUriComponent(), encode: false),
"UriPathBase" => new StringValue(request.PathBase.ToUriComponent(), encode: false),
"UriQueryString" => new StringValue(request.QueryString.ToUriComponent(), encode: false),
_ => ValueTask.FromResult<FluidValue>(NilValue.Instance)
};
}
private static HttpRequest GetHttpRequest(TemplateContext context)
{
var ctx = context as LiquidTemplateContext
?? throw new InvalidOperationException($"An implementation of '{nameof(LiquidTemplateContext)}' is required");
var httpContext = ctx.Services.GetRequiredService<IHttpContextAccessor>().HttpContext;
return httpContext.Request;
}
}
View on GitHub (pinned to 4306c0717f)