Skip to content

offset: continue after a negative offset resumes from a different item than on shopify.dev #2132

Open

Description

@sebastienros

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

{% assign items = '1,2,3' | split: ',' %}
{% for i in items offset: -1 limit: 2 %}{{ i }}{% endfor %}|{% for i in items offset: continue %}{{ i }}{% endfor %}
{% assign items = '1,2,3' | split: ',' %}
{% for i in items offset: -1 %}{{ i }}{% endfor %}|{% for i in items offset: 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

  1. sebastienros commented on Oct 25, 2026

    @sebastienros
    Author

    I am fine with the behavior of this gem but wondering what shopify.dev is using to render the templates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions