OrchardCMS/OrchardCore · error · InvalidOperationException

The ' ' shape has been called recursively more than times.

Error message

The '{shape.Metadata.Type}' shape has been called recursively more than {LiquidTemplateContext.MaxShapeRecursions} times.

What it means

LiquidViewTemplate.EnterScopeAsync tracks shape recursion depth in the Liquid context. When the same IShape instance is entered again while already the current Model and the recursion counter exceeds LiquidTemplateContext.MaxShapeRecursions, an InvalidOperationException is thrown. This prevents infinite shape-recursion (stack overflow / endless rendering) from self-referencing shapes or templates.

Solutions

  1. Break the recursion in the template: render child shapes, not the shape itself
  2. Fix the data cycle (self-referencing content item, menu, or taxonomy)
  3. If depth is legitimately deep, raise the recursion limit configuration for LiquidTemplateContext
  4. Use alternates so nested shapes use a different template and stop re-entering the same scope

Example fix

// before
{{ Model.Items | shape_render }} <!-- template renders itself for each item that is the same shape -->
// after
{% for item in Model.Items %}
    {% assign child = item | shape_properties %}
    {% render_shape child.ChildShape %} <!-- render distinct child shape type -->
{% endfor %}
Defensive patterns

Strategy: validation

Validate before calling

// before rendering a shape in Liquid, ensure it is not the same instance as the current Model
{% if Model.Handle != shape.Handle %}
    {% render_shape shape %}
{% endif %}

Try / catch

try { await template.RenderAsync(...); } catch (InvalidOperationException e) when (e.Message.Contains("recursively")) { _logger.LogError(e, "Shape recursion detected: {0}", e.Message); }

Prevention

When it happens

Trigger: A Liquid template for shape X renders shape X again (directly or via a wrapper/alternate loop), or a shape's display triggers its own template repeatedly (e.g. a list shape containing itself, or a menu item whose template re-displays the parent menu) more than MaxShapeRecursions times.

Common situations: Self-referencing content (a content item linked as its own child), misconfigured menu/term structures with cycles, Liquid templates using {{ Model | shape_render }} on the same shape recursively, placement causes a shape to include itself.

Related errors


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

Appendix: source

Thrown at src/OrchardCore/OrchardCore.DisplayManagement.Liquid/LiquidViewTemplate.cs:242

    {
        await context.InitializeAsync(viewContext);

        context.EnterChildScope();

        var viewLocalizer = context.Services.GetRequiredService<IViewLocalizer>();

        if (viewLocalizer is IViewContextAware contextable)
        {
            contextable.Contextualize(viewContext);
        }

        context.SetValue("ViewLocalizer", new ObjectValue(viewLocalizer));

        if (context.GetValue("Model")?.ToObjectValue() == model && model is IShape shape)
        {
            if (context.ShapeRecursions++ > LiquidTemplateContext.MaxShapeRecursions)
            {
                throw new InvalidOperationException(
                    $"The '{shape.Metadata.Type}' shape has been called recursively more than {LiquidTemplateContext.MaxShapeRecursions} times.");
            }
        }
        else
        {
            context.ShapeRecursions = 0;
        }

        context.SetValue("Model", model);
    }
}

View on GitHub (pinned to 4306c0717f)