Shopify/liquid · error · Liquid::SyntaxError

errors.syntax.for

errors.syntax.for

Error message

options[:locale].t("errors.syntax.for")

What it means

Liquid raises this SyntaxError from the {% for %} tag's lax_parse when the tag markup doesn't match the required 'for <var> in <collection>' shape. The lax parser scans the markup with TagAttributes and, on falling into the else branch, cannot find a valid variable/collection pair. It signals that the for-loop declaration itself is malformed (not the loop body).

Solutions

  1. Fix the for tag to the form {% for item in collection %} with a variable name and a collection expression
  2. If the collection may be empty/nil, ensure the expression is still syntactically present (e.g. {% for item in products %}), guarding emptiness inside the loop
  3. Run the template through Template.parse in a test to catch the SyntaxError at load time instead of render time

Example fix

// before
{% for %} ... {% endfor %}
// after
{% for item in products %} ... {% endfor %}
Defensive patterns

Strategy: validation

Validate before calling

markup = tag_markup # the text between {% for and %}
valid = markup =~ /\A\s*[\w\-]+\s+in\s+.+\s*\z/
raise Liquid::SyntaxError, 'for tag must be: for <var> in <collection>' unless valid

Type guard

def valid_for_tag?(markup)
  !!(markup.to_s =~ /\A\s*[\w\-\"']+\s+in\s+\S/)
end

Try / catch

begin
  Liquid::Template.parse(template)
rescue Liquid::SyntaxError => e
  logger.error("Liquid for-tag syntax: #{e.message}")
  fallback_template
end

Prevention

When it happens

Trigger: A {% for %} tag whose markup lacks the 'in' structure, e.g. {% for %}, {% for item %}, or {% for in items %}; any for tag failing lax mode syntax parsing in parse.liquid templates rendered with the default (lax) parser.

Common situations: Hand-edited templates with a deleted variable or collection expression; template strings built dynamically via interpolation where a variable came out empty; copy-paste from docs that dropped the 'item in collection' part.

Related errors


AI-assisted analysis of Shopify/liquid@807d45a6b3 (2026-09-08). Data as JSON: /api/errors/61665208b6920df0. Report an issue: GitHub.

Appendix: source

Thrown at lib/liquid/tags/for.rb:86

      end

      output
    end

    protected

    def lax_parse(markup)
      if markup =~ Syntax
        @variable_name   = Regexp.last_match(1)
        collection_name  = Regexp.last_match(2)
        @reversed        = !!Regexp.last_match(3)
        @name            = "#{@variable_name}-#{collection_name}"
        @collection_name = parse_expression(collection_name)
        markup.scan(TagAttributes) do |key, value|
          set_attribute(key, value)
        end
      else
        raise SyntaxError, options[:locale].t("errors.syntax.for")
      end
    end

    def strict_parse(markup)
      p = @parse_context.new_parser(markup)
      @variable_name = p.consume(:id)
      raise SyntaxError, options[:locale].t("errors.syntax.for_invalid_in") unless p.id?('in')

      collection_name  = p.expression
      @collection_name = parse_expression(collection_name, safe: true)

      @name     = "#{@variable_name}-#{collection_name}"
      @reversed = p.id?('reversed')

      while p.look(:comma) || p.look(:id)
        p.consume?(:comma)
        unless (attribute = p.id?('limit') || p.id?('offset'))
          raise SyntaxError, options[:locale].t("errors.syntax.for_invalid_attribute")

View on GitHub (pinned to 807d45a6b3)