You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
offset: continue after a negative offset resumes from a different item than on shopify.dev #2132
After a for loop with a negative offset, offset: continue resumes from a different item in this gem than in the renderer behind the shopify.dev Liquid examples.
Repro
{% assignitems = '1,2,3' | split:',' %}
{% foriinitemsoffset:-1limit:2 %}{{ i }}{% endfor %}|{% foriinitemsoffset:continue %}{{ i }}{% endfor %}
{% assignitems = '1,2,3' | split:',' %}
{% foriinitemsoffset:-1 %}{{ i }}{% endfor %}|{% foriinitemsoffset:continue %}{{ i }}{% endfor %}
Results
Template
Shopify/liquid (v5.14.0, also v5.0.0)
shopify.dev renderer
offset: -1 limit: 2, then offset: continue
1|123
1|23
offset: -1, then offset: continue
123|3
123|
Both engines agree on the first loop: it starts at the first item and still ends at offset + limit, so offset: -1 limit: 2 renders only 1. They disagree on where the second loop resumes.
Gem:For#collection_segment stores offsets[@name] = from + segment.length with the unclamped from. The cursor becomes -1 + 1 = 0 in the first case and -1 + 3 = 2 in the second. This line has been unchanged since 2008.
shopify.dev: the cursor behaves as if from were clamped to 0 first, giving 0 + 1 = 1 and 0 + 3 = 3.
Gem results come from Liquid::Template.parse(source).render on Ruby 4.0.1. The shopify.dev results can be reproduced by running the templates in the examples at https://shopify.dev/docs/api/liquid.
Question
Which behavior is intended? If shopify.dev is correct, clamping from for the cursor (for example offsets[@name] = [from, 0].max + segment.length) would align the gem.
Activity
sebastienros commentedon Oct 25, 2026
I am fine with the behavior of this gem but wondering what shopify.dev is using to render the templates.