{"record":{"id":"8eafe92784da0040","repo":"Shopify/liquid","slug":"nesting-too-deep-8eafe9","errorCode":null,"errorMessage":"Nesting too deep","messagePattern":"Nesting too deep","errorType":"exception","errorClass":"Liquid::StackLevelError","httpStatus":null,"severity":"error","filePath":"lib/liquid/context.rb","lineNumber":288,"sourceCode":"\n    def try_variable_find_in_environments(key, raise_on_not_found:)\n      @environments.each do |environment|\n        found_variable = lookup_and_evaluate(environment, key, raise_on_not_found: raise_on_not_found)\n        if !found_variable.nil? || @strict_variables && raise_on_not_found\n          return found_variable\n        end\n      end\n      @static_environments.each do |environment|\n        found_variable = lookup_and_evaluate(environment, key, raise_on_not_found: raise_on_not_found)\n        if !found_variable.nil? || @strict_variables && raise_on_not_found\n          return found_variable\n        end\n      end\n      nil\n    end\n\n    def check_overflow\n      raise StackLevelError, \"Nesting too deep\" if overflow?\n    end\n\n    def overflow?\n      base_scope_depth + @scopes.length > Block::MAX_DEPTH\n    end\n\n    def internal_error\n      # raise and catch to set backtrace and cause on exception\n      raise Liquid::InternalError, 'internal'\n    rescue Liquid::InternalError => exc\n      exc\n    end\n\n    def squash_instance_assigns_with_environments\n      @scopes.last.each_key do |k|\n        @environments.each do |env|\n          if env.key?(k)\n            scopes.last[k] = lookup_and_evaluate(env, k)","sourceCodeStart":270,"sourceCodeEnd":306,"githubUrl":"https://github.com/Shopify/liquid/blob/807d45a6b3d4568e64e86b375e3702df2c7c860c/lib/liquid/context.rb#L270-L306","documentation":"Liquid raises StackLevelError via Context#check_overflow when the template's block nesting exceeds Block::MAX_DEPTH. This guards against runaway recursion in templates (e.g. deeply nested for/if blocks or recursive includes) that would otherwise blow the Ruby stack. It is a protective limit, not a bug in your template data.","triggerScenarios":"Parsing or rendering a template whose nested block depth (base_scope_depth + scopes) exceeds Block::MAX_DEPTH — e.g. an {% include %} that includes itself, or hundreds of nested {% for %}/{% if %} blocks.","commonSituations":"Recursive or mutually-recursive includes/partials generated programmatically; templating tools that build deeply nested DOM wrappers; user-supplied templates crafted (maliciously or accidentally) to nest deeply.","solutions":["Find and break the recursion or reduce nesting depth in the template (often a self-including partial).","If your use case legitimately needs more depth, raise Block::MAX_DEPTH in an initializer (accepting deeper Ruby stack usage).","Set a depth/size limit on user-supplied templates before parsing.","Wrap render in error handling and report the offending template to the user."],"exampleFix":"// before\n{% include 'wrapper' %}  # wrapper.liquid contains {% include 'wrapper' %}\n// after\n{% include 'wrapper' %}  # wrapper.liquid contains real content, no self-include","handlingStrategy":"validation","validationCode":"def template_depth_ok?(source)\n  max_nesting = 0; cur = 0\n  source.scan(/\\{%-?\\s*(if|unless|case|for|tablerow|capture|include)\\b/) { cur += 1; max_nesting = [max_nesting, cur].max }\n  source.scan(/\\{%-?\\s*end\\w+/) { cur -= 1 }\n  max_nesting <= 50 # keep below Block::MAX_DEPTH\nend","typeGuard":"def safe_parse?(source)\n  Liquid::Template.parse(source)\n  true\nrescue Liquid::StackLevelError\n  false\nend","tryCatchPattern":"begin\n  Liquid::Template.parse(src).render(ctx)\nrescue Liquid::StackLevelError => e\n  logger.warn(\"Template nesting too deep: #{e.message}\")\n  render_fallback_template\nend","preventionTips":["Never allow templates to include themselves; enforce an include-depth budget.","Lint templates for nesting depth before deploying.","Keep Block::MAX_DEPTH defaults unless you have measured stack headroom.","Reject user-supplied templates with excessive block nesting up front."],"tags":["ruby","liquid","recursion","stack-depth"],"backgroundTag":"value-out-of-range","analyzedSha":"807d45a6b3d4568e64e86b375e3702df2c7c860c","analyzedAt":"2026-09-08T11:31:38.917Z","contentChangedAt":"2026-09-08T11:31:38.917Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}