Shopify/liquid · error · Liquid::SyntaxError

errors.syntax.case

errors.syntax.case

Error message

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

What it means

A `case` tag must be followed by an expression to switch on, matching Case::Syntax /(QuotedFragment)/. lax_parse (shared with strict_parse) raises SyntaxError with 'errors.syntax.case' when the markup between `{% case %}` and `%}` contains no quotable fragment/expression.

Solutions

  1. Supply the variable to switch on: {% case product.type %} ... {% endcase %}
  2. Ensure the expression is a valid Liquid variable or literal (QuotedFragment), e.g. handle.title or "x"
  3. If you need no condition, use if/else instead of case
  4. Validate templates at build time to surface the error with template name and line

Example fix

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

Strategy: validation

Validate before calling

def valid_case_markup?(markup)
  !markup.strip.empty? && markup =~ /[\w"']/
end

Try / catch

begin
  Liquid::Template.parse(source)
rescue Liquid::SyntaxError => e
  notify("case tag missing expression: #{e.message}")
end

Prevention

When it happens

Trigger: {% case %} with empty markup ({% case %} ... {% endcase %}), or markup consisting only of operators/whitespace with no variable or literal.

Common situations: Deleting the variable while refactoring case/when blocks; template engines or formatters stripping arguments; users confusing `{% case %}` with a bare switch statement from other languages.

Related errors


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

Appendix: source

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

    end

    private

    def strict2_parse(markup)
      parser = @parse_context.new_parser(markup)
      @left = safe_parse_expression(parser)
      parser.consume(:end_of_string)
    end

    def strict_parse(markup)
      lax_parse(markup)
    end

    def lax_parse(markup)
      if markup =~ Syntax
        @left = parse_expression(Regexp.last_match(1))
      else
        raise SyntaxError, options[:locale].t("errors.syntax.case")
      end
    end

    def record_when_condition(markup)
      body = new_body

      if strict2_mode?
        parse_strict2_when(markup, body)
      else
        parse_lax_when(markup, body)
      end
    end

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

      loop do
        expr = Condition.parse_expression(parse_context, parser.expression, safe: true)

View on GitHub (pinned to 807d45a6b3)