{"record":{"id":"f0183d9ec9a9e799","repo":"OrchardCMS/OrchardCore","slug":"an-implementation-of-liquidtemplatecontext-is-required-f0183d","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/TrackingConsentValue.cs","lineNumber":68,"sourceCode":"        {\n            return NilValue.Instance;\n        }\n\n        return name switch\n        {\n            nameof(ITrackingConsentFeature.CanTrack) => BooleanValue.Create(feature.CanTrack),\n            nameof(ITrackingConsentFeature.HasConsent) => BooleanValue.Create(feature.HasConsent),\n            nameof(ITrackingConsentFeature.IsConsentNeeded) => BooleanValue.Create(feature.IsConsentNeeded),\n            \"CookieName\" => new StringValue(GetCookiePolicyOptions(context)?.ConsentCookie?.Name ?? string.Empty),\n            \"CookieValue\" => new StringValue(GetCookiePolicyOptions(context)?.ConsentCookieValue ?? string.Empty),\n            _ => NilValue.Instance\n        };\n    }\n\n    private static ITrackingConsentFeature? GetTrackingFeature(TemplateContext context)\n    {\n        var ctx = context as LiquidTemplateContext\n            ?? throw new InvalidOperationException($\"An implementation of '{nameof(LiquidTemplateContext)}' is required\");\n\n        var httpContext = ctx.Services.GetRequiredService<IHttpContextAccessor>().HttpContext;\n\n        return httpContext?.Features.Get<ITrackingConsentFeature>();\n    }\n\n    private static CookiePolicyOptions? GetCookiePolicyOptions(TemplateContext context)\n    {\n        var ctx = context as LiquidTemplateContext\n            ?? throw new InvalidOperationException($\"An implementation of '{nameof(LiquidTemplateContext)}' is required\");\n\n        return ctx.Services.GetService<IOptions<CookiePolicyOptions>>()?.Value;\n    }\n}\n","sourceCodeStart":50,"sourceCodeEnd":83,"githubUrl":"https://github.com/OrchardCMS/OrchardCore/blob/4306c0717fe573f6fca1b4955909ddab6a192807/src/OrchardCore/OrchardCore.DisplayManagement.Liquid/Values/TrackingConsentValue.cs#L50-L83","documentation":"The `consent` Liquid value needs the browser's ITrackingConsentFeature, resolved through LiquidTemplateContext.Services -> IHttpContextAccessor -> HttpContext.Features. A non-Liquid TemplateContext fails the cast and throws this InvalidOperationException; note that even with a correct context, GetTrackingFeature may still return null when the feature is absent (HttpContext null or no consent feature registered).","triggerScenarios":"Evaluating `{{ consent }}` or its members (e.g. `{{ consent.track }}`, `{{ consent.granted }}`) in a template rendered with a base Fluid TemplateContext.","commonSituations":"Custom rendering of Liquid templates in workers/tests without LiquidTemplateContext; privacy/cookie-consent snippets evaluated by an external template host; missing cookie-consent feature combined with the cast guard in custom pipelines.","solutions":["Render with a LiquidTemplateContext carrying the scoped service provider.","Render through Orchard's ILiquidTemplateManager / Liquid view pipeline instead of raw Fluid APIs.","In C# code outside templates, get ITrackingConsentFeature from IHttpContextAccessor.HttpContext.Features directly and null-check it."],"exampleFix":"// before\nvar context = new TemplateContext();\nvar out = await template.RenderAsync(context);\n// after\nvar context = new LiquidTemplateContext(sp, memberAccessor);\nvar out = await template.RenderAsync(context);","handlingStrategy":"type-guard","validationCode":"if (context is not LiquidTemplateContext) throw new InvalidOperationException(\"consent value requires a LiquidTemplateContext\");","typeGuard":"bool IsLiquidContext(TemplateContext ctx) => ctx is LiquidTemplateContext;","tryCatchPattern":"try { var html = await template.RenderAsync(ctx); } catch (InvalidOperationException ex) when (ex.Message.Contains(\"LiquidTemplateContext\")) { /* create LiquidTemplateContext; also null-check the consent feature */ }","preventionTips":["Enable the Cookie Consent feature before using consent checks in templates.","Null-check `httpContext?.Features.Get<ITrackingConsentFeature>()` in custom code.","Render consent-related templates only via the standard Liquid pipeline."],"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-15T23:17:13.987Z"}