{"record":{"id":"44c95f097dc89ef3","repo":"OrchardCMS/OrchardCore","slug":"an-implementation-of-liquidtemplatecontext-is-required-44c95f","errorCode":null,"errorMessage":"An implementation of 'LiquidTemplateContext' is required","messagePattern":"An implementation of 'LiquidTemplateContext' is required","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/OrchardCore/OrchardCore.DisplayManagement.Liquid/Values/HttpContextValue.cs","lineNumber":55,"sourceCode":"    {\n        var httpContext = GetHttpContext(context);\n\n        if (httpContext is null)\n        {\n            return new ValueTask<FluidValue>(NilValue.Instance);\n        }\n\n        return name switch\n        {\n            nameof(HttpContext.Items) => new ObjectValue(new HttpContextItemsWrapper(httpContext.Items)),\n            _ => NilValue.Instance\n        };\n    }\n\n    private static HttpContext GetHttpContext(TemplateContext context)\n    {\n        var ctx = context as LiquidTemplateContext\n            ?? throw new InvalidOperationException($\"An implementation of '{nameof(LiquidTemplateContext)}' is required\");\n\n        var httpContextAccessor = ctx.Services.GetRequiredService<IHttpContextAccessor>();\n\n        return httpContextAccessor.HttpContext;\n    }\n}\n","sourceCodeStart":37,"sourceCodeEnd":62,"githubUrl":"https://github.com/OrchardCMS/OrchardCore/blob/4306c0717fe573f6fca1b4955909ddab6a192807/src/OrchardCore/OrchardCore.DisplayManagement.Liquid/Values/HttpContextValue.cs#L37-L62","documentation":"The `http_context` Liquid value resolves the current HttpContext by casting the TemplateContext to LiquidTemplateContext to access `ctx.Services` and `IHttpContextAccessor`. If evaluation happens with a plain Fluid TemplateContext, the cast fails and this InvalidOperationException is thrown before the accessor is even consulted.","triggerScenarios":"Accessing `{{ http_context }}` or its members (request, user, items, etc.) from a template rendered with a non-Liquid TemplateContext — custom render loops, tests, or direct FluidValue member invocation.","commonSituations":"Precompiling/testing Liquid templates with a hand-rolled context; rendering templates inside hosted services using the Fluid API directly; framework upgrades where custom code still creates the old base TemplateContext.","solutions":["Use LiquidTemplateContext (with the request-scoped IServiceProvider) when rendering any template that touches `http_context`.","Render via ILiquidTemplateManager / the Liquid shape or view pipeline rather than raw Fluid APIs.","For non-Liquid code, inject IHttpContextAccessor in C# instead of going through Liquid values."],"exampleFix":"// before\nvar ctx = new TemplateContext();\nawait template.RenderAsync(ctx);\n// after\nvar ctx = new LiquidTemplateContext(httpContext.RequestServices, memberAccessor);\nawait template.RenderAsync(ctx);","handlingStrategy":"type-guard","validationCode":"if (context is not LiquidTemplateContext) throw new InvalidOperationException(\"http_context requires a LiquidTemplateContext with IHttpContextAccessor\");","typeGuard":"bool IsLiquidContext(TemplateContext ctx) => ctx is LiquidTemplateContext;","tryCatchPattern":"try { await template.RenderAsync(ctx); } catch (InvalidOperationException ex) when (ex.Message.Contains(\"LiquidTemplateContext\")) { /* construct LiquidTemplateContext with RequestServices */ }","preventionTips":["Use RequestServices (request-scoped provider) when building LiquidTemplateContext.","Avoid evaluating templates that touch http_context outside an active HTTP request.","Inject IHttpContextAccessor in C# code instead of round-tripping through Liquid."],"tags":["liquid","fluid","type-cast","orchardcore"],"backgroundTag":"type-mismatch","analyzedSha":"4306c0717fe573f6fca1b4955909ddab6a192807","analyzedAt":"2026-09-13T17:41:05.024Z","contentChangedAt":"2026-09-13T17:41:05.024Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}