Shopify/liquid · error · Liquid::SyntaxError

errors.syntax.case_invalid_when

errors.syntax.case_invalid_when

Error message

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

What it means

Each `{% when %}` inside a case block must contain one or more values separated by `or` or commas, matching WhenSyntax. parse_lax_when raises SyntaxError with 'errors.syntax.case_invalid_when' when a when clause's markup contains no QuotedFragment.

Solutions

  1. Give each when clause at least one literal or variable: {% when "shirt" %}
  2. Separate multiple values with 'or' or a comma: {% when "a" or "b" %} / {% when 1, 2 %}
  3. Remove unsupported operators (> , and, ranges) from when clauses; use nested {% if %} for such logic
  4. Wrap when values containing special characters in quotes

Example fix

// before
{% when product.type == "shirt" %}
// after
{% when "shirt" %}
Defensive patterns

Strategy: validation

Validate before calling

def valid_when_markup?(markup)
  markup =~ /\s*[\w"']/ # at least one value literal/variable present
end

Try / catch

begin
  Liquid::Template.parse(source)
rescue Liquid::SyntaxError => e
  raise "Invalid when clause: #{e.message}"
end

Prevention

When it happens

Trigger: `{% when %}` with empty markup; `{% when a and b %}` (using 'and' instead of 'or'); when clauses with expressions the regex cannot parse like `{% when x > 1 %}`.

Common situations: Translating switch/case code from other languages using 'and' or '||'; typos dropping the value after `when`; trying to do range comparisons in `when`, which Liquid does not support.

Related errors


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

Appendix: source

Thrown at lib/liquid/tags/case.rb:135

    def parse_strict2_when(markup, body)
      parser = @parse_context.new_parser(markup)

      loop do
        expr = Condition.parse_expression(parse_context, parser.expression, safe: true)
        block = Condition.new(@left, '==', expr)
        block.attach(body)
        @blocks << block

        break unless parser.id?('or') || parser.consume?(:comma)
      end

      parser.consume(:end_of_string)
    end

    def parse_lax_when(markup, body)
      while markup
        unless markup =~ WhenSyntax
          raise SyntaxError, options[:locale].t("errors.syntax.case_invalid_when")
        end

        markup = Regexp.last_match(2)

        block = Condition.new(@left, '==', Condition.parse_expression(parse_context, Regexp.last_match(1)))
        block.attach(body)
        @blocks << block
      end
    end

    def record_else_condition(markup)
      unless markup.strip.empty?
        raise SyntaxError, options[:locale].t("errors.syntax.case_invalid_else")
      end

      block = ElseCondition.new
      block.attach(new_body)
      @blocks << block

View on GitHub (pinned to 807d45a6b3)