Skip to content

Comments

Fix render named-argument shadowing by evaluating assignments before applying them#924

Merged
sebastienros merged 2 commits intomainfrom
copilot/fix-variable-corruption-render-tag
Feb 16, 2026
Merged

Fix render named-argument shadowing by evaluating assignments before applying them#924
sebastienros merged 2 commits intomainfrom
copilot/fix-variable-corruption-render-tag

Conversation

Copy link
Contributor

Copilot AI commented Feb 16, 2026

render keyword arguments were applied sequentially in the active render scope, so an early assignment could overwrite a variable needed by later argument expressions (e.g. value: value.f1, key: value.f2). This produced corrupted results when argument names overlapped with source objects.

  • Behavioral fix (RenderStatement)

    • Changed render named-argument handling to:
      1. evaluate all assignment expressions first,
      2. then apply all resulting values to the render scope.
    • This preserves the original lookup context across all argument evaluations and aligns with expected Liquid behavior.
  • Regression coverage

    • Added a focused test for:
      • source: {% render 'file', value: value.f1, key: value.f2 %}
      • snippet: {{ value }} {{ key }}
      • expected output: Hello World
  • Scope of change

    • Limited to render assignment evaluation flow; no parser or syntax changes.
{% render 'file', value: value.f1, key: value.f2 %}

Before: first assignment could replace value and break value.f2 resolution.
After: both expressions resolve against the same pre-assignment context, then are assigned.

Original prompt

This section details on the original issue you should resolve

<issue_title>Bug: Variable corruption in render tag assignments</issue_title>
<issue_description>Found a bug while working with Shopify's Horizon theme. When a render tag has multiple assignments and one of the parameter names matches an object that's referenced in later assignments, the object value gets corrupted.

list-filter.liquid#L369-L378:

{% render 'checkbox',
  name: value.param_name,
  value: value.value,
  label: value.label,
  checked: value.active,
  id: input_id,
  disabled: is_disabled,
  inputRef: 'facetInputs[]',
  events: 'on:pointerenter="/prefetchPage" on:pointerleave="/cancelPrefetchPage"',
  autofocus: autofocus
%}

Notice how value is used as both a parameter name and as the object being accessed (value.value, value.label, etc.).

Sample

var source = "{% render 'file', value: value.f1, key: value.f2 %}";
var file = "{{value}} {{key}}";

if (new FluidParser().TryParse(source, out var template, out var error))
{
    var context = new TemplateContext();
	
    var fileProvider = new MockFileProvider();
    fileProvider.Add("file", file);
    context.Options.FileProvider = fileProvider;

    context.SetValue("value", new MyClass { f1 = "Hello", f2 = "World" });

    Console.WriteLine(template.Render(context));
}

Expected output:

Hello World

Actual output:

Hello 

Analysis

It appears that assignments are being evaluated and applied to the context sequentially, so when value: value.f1 is processed:

  1. value.f1 is evaluated correctly as "Hello"
  2. value is set to "Hello" in the context
  3. When key: value.f2 is evaluated, value is now "Hello" (a string), not the original object, so .f2 fails

The assignments should all be evaluated first using the original context, then applied together.</issue_description>

Comments on the Issue (you are @copilot in this section)

@hishamco Please submit a PR, or I could have a look @sebastienros Can you try with [3.0.0-beta.4](https://www.nuget.org/packages/Fluid.Core/3.0.0-beta.4) which I just published? It contains tons of bug fixes to align with Shopify's implementation. This was done by working on all the tests provided by https://github.com/jg-rp/golden-liquid

And please report on the other issues you filed after testing with this version, where it applies.</comment_new>


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Co-authored-by: sebastienros <1165805+sebastienros@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix variable corruption in render tag assignments Fix render named-argument shadowing by evaluating assignments before applying them Feb 16, 2026
Copilot AI requested a review from sebastienros February 16, 2026 18:09
@sebastienros sebastienros marked this pull request as ready for review February 16, 2026 18:14
@sebastienros sebastienros merged commit 6283e73 into main Feb 16, 2026
3 checks passed
@sebastienros sebastienros deleted the copilot/fix-variable-corruption-render-tag branch February 16, 2026 18:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Variable corruption in render tag assignments

2 participants