OrchardCMS/OrchardCore · error · ArgumentException

HttpRequest missing while invoking 'switch_culture_url'

Error message

HttpRequest missing while invoking 'switch_culture_url'

What it means

The switch_culture_url Liquid filter builds a URL that redirects to the localized version of the current content. It needs the current HttpRequest to resolve the route; when HttpContext or its Request is unavailable (e.g. rendering a Liquid template outside an HTTP request) it throws ArgumentException.

Solutions

  1. Only use switch_culture_url in templates rendered during an HTTP request.
  2. In background flows, build the URL explicitly with IUrlHelper/LinkGenerator using a configured base URL instead of the filter.
  3. Guard the template with an http-context availability check, or supply an IHttpContextAccessor-backed DefaultHttpContext.
  4. Wrap rendering in try/catch and fall back to a plain culture-neutral link.

Example fix

// before
var url = await template.RenderAsync(...); // template uses switch_culture_url, no HttpContext
// after
var url = _linkGenerator.GetPathByRouteName("RedirectToLocalizedContent", new { area = "OrchardCore.ContentLocalization", culture = "fr" });
Defensive patterns

Strategy: fallback

Validate before calling

{% if http_context %}{{ content | switch_culture_url: 'fr' }}{% else %}/fr{{ content | display_text }}{% endif %}

Type guard

static bool HasRequest(LiquidTemplateContext ctx) => ctx.ViewContext?.HttpContext?.Request is not null;

Try / catch

try { url = await filter.ProcessAsync(input, args, ctx); }
catch (ArgumentException ex) when (ex.Message.Contains("switch_culture_url"))
{ url = fallbackPath; logger.LogDebug("switch_culture_url used outside HTTP context; using fallback"); }

Prevention

When it happens

Trigger: Using {{ content | switch_culture_url: 'fr' }} in a template rendered without a ViewContext/HttpContext — background email/liquid templating jobs, workflow activities without an HTTP context, or unit tests rendering templates directly.

Common situations: Sending Liquid-rendered notification emails from a background task; rendering templates in workflow scheduled events; running template previews in a console/hosted service.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13). Data as JSON: /api/errors/b1b4a98cc81f5577. Report an issue: GitHub.

Appendix: source

Thrown at src/OrchardCore.Modules/OrchardCore.ContentLocalization/Liquid/SwitchCultureUrlFilter.cs:26

namespace OrchardCore.ContentLocalization.Liquid;

public class SwitchCultureUrlFilter : ILiquidFilter
{
    private readonly IUrlHelperFactory _urlHelperFactory;
    private readonly IHttpContextAccessor _httpContextAccessor;

    public SwitchCultureUrlFilter(IUrlHelperFactory urlHelperFactory, IHttpContextAccessor httpContextAccessor)
    {
        _urlHelperFactory = urlHelperFactory;
        _httpContextAccessor = httpContextAccessor;
    }

    public ValueTask<FluidValue> ProcessAsync(FluidValue input, FilterArguments arguments, LiquidTemplateContext context)
    {
        var urlHelper = _urlHelperFactory.GetUrlHelper(context.ViewContext);

        var request = _httpContextAccessor.HttpContext?.Request
            ?? throw new ArgumentException("HttpRequest missing while invoking 'switch_culture_url'");

        var targetCulture = input.ToStringValue();

        var url = urlHelper.RouteUrl("RedirectToLocalizedContent",
            new
            {
                area = "OrchardCore.ContentLocalization",
                targetCulture,
                contentItemUrl = request.Path.Value,
                queryStringValue = request.QueryString.Value,
            });
        return ValueTask.FromResult(FluidValue.Create(url, context.Options));
    }
}

View on GitHub (pinned to 4306c0717f)