Skip to main content

Migrate to Liquid's strictest parser

Liquid now ships with a stricter error mode. Previously, Liquid would allow certain code patterns which appear to be well formed, but which the language doesn't yet support. Liquid's parser would accept this code, but evaluate it incorrectly.

To develop the Liquid language so that these types of code patterns can be supported in the future, we’ve updated the parser to be stricter about the code it accepts.

For example, instead of accepting assign x = false or true and evaluating x to be false, the new stricter error mode reports that this code can’t be parsed. This change means that we’ll be able to update Liquid in the future so it can accept assign x = false or true and correctly evaluate the expression to true.

In the following example, the previous parser would suppress the syntax error caused by trying to assign a logical expression to a variable and would never render Important content.

snippets/example.liquid

{% assign x = false or true %}
{% if x %}
Important content
{% endif %}

We've put together a list of common errors we've seen across themes and theme app extensions to help the transition:


Anchor to Expected end_of_string but found pipeExpected end_of_string but found pipe

Anchor to Filters in render tagsFilters in render tags

Using filters outside of variable output, assign and the echo tag throws a syntax error:

snippets/example.liquid

{% render 'image', image: image, alt: image.alt | escape %}

Fix by pulling the filter outside of the render tag and into its own variable:

snippets/example.liquid

{% assign alt_text = image.alt | escape %}
{% render 'image', image: image, alt: alt_text %}

Anchor to Expected end_of_string but found comparisonExpected end_of_string but found comparison

Anchor to Conditional expressions in render tagsConditional expressions in render tags

Using conditional expressions as a value for a render argument throws a syntax error:

snippets/example.liquid

{%
render 'product-card',
product: product,
show_description: settings.x or settings.y,
%}

Fix by wrapping the render tag with the conditional expression:

snippets/example.liquid

{% if settings.x or settings.y %}
{%
render 'product-card',
product: product,
show_description: true,
%}
{% endif %}

Anchor to Expected end_of_string but found colonExpected end_of_string but found colon

You can pass a single object to a snippet using the with parameter but also including a key value pair causes a syntax error:

snippets/example.liquid

{% render 'icon' with style: 'lock' %}

Fix by removing with:

snippets/example.liquid

{% render 'icon', style: 'lock' %}

Another version of this error you might see is raised as [:colon, ":"] is not a valid expression which you'll see if you use a colon immediately after with. Similarly to above, fix by removing with::

snippets/example.liquid

- {% render 'icon', with: style: 'lock' %}
+ {% render 'icon', style: 'lock' %}

If you want to keep the behavior of with (which in the error example above assigns the value of style to icon, see documentation for more details) then you can specify it like this:

snippets/example.liquid

{% assign style = 'lock' %}
{% render 'icon' with style %}

Anchor to Malformed arguments in render tagMalformed arguments in render tag

Missing a value for the responsive attribute:

snippets/example.liquid

{% render 'image', lazyload: lazyload, responsive: width: 500 %}

Fix by adding a value for responsive:

snippets/example.liquid

{% render 'image', lazyload: lazyload, responsive: true, width: 500 %}

Anchor to Expected end_of_string but found idExpected end_of_string but found id

Anchor to Logical operators in variable assignmentsLogical operators in variable assignments

Logical operators can only be used in if statements. The following throws a syntax error:

snippets/example.liquid

{% liquid
assign x = settings.y or settings.z

if x
# logic
endif
%}

Fix by moving the conditional expression into the if statement:

snippets/example.liquid

{% liquid
if settings.y or settings.z
# logic
endif
%}

Anchor to Logical operators in case statementsLogical operators in case statements

Just like variables, case statements can't use logical operators:

snippets/example.liquid

{% liquid
case template.name
when 'product'
# product logic
when 'collection' and settings.x
# collection logic
else
# all other templates
endcase %}

Depending on the scenario you might need to rework your business logic but the example above could be refactored to be like this:

snippets/example.liquid

{% liquid
case template.name
when 'product'
# product logic
when 'collection'
if settings.x
# collection logic
endif
else
# all other templates
endcase %}

Anchor to Expected colon but found end_of_stringExpected colon but found end_of_string

Anchor to Malformed arguments passed to render tagMalformed arguments passed to render tag

snippets/example.liquid

{% render 'image', lazyload: lazyload, responsive %}

Fix by adding a value for responsive:

snippets/example.liquid

{% render 'image', lazyload: lazyload, responsive: true %}

Anchor to Expected colon but found commaExpected colon but found comma

Anchor to Malformed arguments passed to render tagMalformed arguments passed to render tag

snippets/example.liquid

{% render 'related-products', product, collection %}

Variables passed to a snippet need to be formatted as key value pairs:

snippets/example.liquid

{% render 'related-products', product: product, collection: collection %}

Anchor to Unexpected charactersUnexpected characters

This is an all encompassing error that can sometimes be hard to parse where the exact issue is. In most cases the problem is a typo but the line number on the error should help point you to the exact spot. Provided are some common examples we've seen but this isn't an exhaustive list:

Conditional expressions in Liquid use and and or. Using && and || throws a syntax error:

snippets/example.liquid

{% liquid
if responsive && settings.x || settings.y
render 'responsive-image', image: image
endif
%}

Fix by using Liquid's boolean operators:

snippets/example.liquid

{% liquid
if responsive and settings.x or settings.y
render 'responsive-image', image: image
endif
%}

Anchor to Conditional expressions using parenthesesConditional expressions using parentheses

Using parentheses to group conditional expressions throws a syntax error:

snippets/example.liquid

{% liquid
if responsive and (settings.x or settings.y)
render 'responsive-image', image: image
endif
%}

Fix by removing the parentheses (and read the documentation on the order in which Liquid parses conditional expressions):

snippets/example.liquid

{% liquid
if responsive and settings.x or settings.y
render 'responsive-image', image: image
endif
%}

Anchor to Invalid expressions used in case statementInvalid expressions used in case statement

The following results in Liquid syntax error (line 3): Unexpected character =:

snippets/example.liquid

{% liquid
case media.preview_image.width
when => 550
assign media_largest = media.preview_image | image_url: width: 550 | append: '550w'
when => 1100
assign media_largest = media.preview_image | image_url: width: 1100 | append: '1100w'
# etc...
endcase
%}

To fix this remove the =>:

snippets/example.liquid

{% liquid
case media.preview_image.width
when 550
assign media_largest = media.preview_image | image_url: width: 550 | append: '550w'
when 1100
assign media_largest = media.preview_image | image_url: width: 1100 | append: '1100w'
# etc...
endcase
%}

Anchor to Comments must be written on their own lineComments must be written on their own line

The following results in Liquid syntax error (line 5): Unexpected character #:

snippets/example.liquid

{% liquid
case media.preview_image.width
when 550
assign media_largest = media.preview_image | image_url: width: 550 | append: '550w'
when 1100 # this is a comment about this size
assign media_largest = media.preview_image | image_url: width: 1100 | append: '1100w'
# etc...
endcase
%}

To fix this, move the comment to its own line:

snippets/example.liquid

{% liquid
case media.preview_image.width
when 550
assign media_largest = media.preview_image | image_url: width: 550 | append: '550w'
when 1100
# this is a comment about this size
assign media_largest = media.preview_image | image_url: width: 1100 | append: '1100w'
# etc...
endcase
%}

Anchor to [object Object], is not a valid expression[:end_of_string] is not a valid expression

Anchor to Malformed arguments passed to render tagMalformed arguments passed to render tag

snippets/example.liquid

{% render 'icon', style: %}

Fix by adding a value for style::

snippets/example.liquid

{% render 'icon', style: 'lock' %}

Was this page helpful?