The wrong variant gets added to the cart

Topic summary

A user implemented a custom threshold to treat product variants with stock levels of three or less as sold out, successfully greying out low-stock options. However, this created a cart bug where selecting one variant (e.g., “30 ml”) added a different variant (e.g., “100 ml”) instead.

Technical Context:

  • Theme: Be Yours
  • Modified files: product-variant-options.liquid and product-variant-picker.liquid
  • Code snippets were shared showing custom stock-checking logic integrated with variant selection

Resolution:
The user resolved the issue independently by changing approach—hiding low-stock variant buttons entirely rather than disabling them. This preserved add-to-cart functionality without triggering the wrong-variant bug. Case closed.

Summarized with AI on October 28. AI used: claude-sonnet-4-5-20250929.

Hi,

I want to be able to set a threshold on products that have multiple variants so that any variant with a stock level of three or less is treated as sold out. I’ve gotten some help along the way and the function now works: variants with low stock levels are greyed out and unselectable.

However, another bug has cropped up: the wrong variant ends up in the cart. For example, if you choose to buy the “30 ml” variant on this example , the first available variant is added to the cart instead (in this case, 100 ml). We can’t find any solution at all. Does anyone have any ideas?

The theme is Be Yours, and the modified files are product-variant-options.liquid and product-variant-picker.liquid. Thanks!

Hi Markit-Themes,

Thanks a lot for stopping by.

Here is the modified product-variant-options.liquid

{% comment %}
  Renders product variant options

  Accepts:
  - product: {Object} product object.
  - option:  {Object} current product_option object.
  - block:   {Object} block object.
  - picker_type: {String} type of picker to display

  Usage:
  {% render 'product-variant-options',
    product: product,
    option: option,
    block: block,
    picker_type: picker_type
  %}
{% endcomment %}

{%- liquid
  assign product_form_id = 'product-form-' | append: section.id
  assign has_set_default = false
-%}

{%- for value in option.values -%}
  {%- liquid
    # --- SWATCH / DROPDOWN-LOGIK (oförändrad) ---
    assign swatch_focal_point = null
    assign swatch_value       = value | split: ' ' | last | handle

    if block.settings.swatch_source == 'native'
      if value.swatch.image
        assign image_url         = value.swatch.image | image_url: width: 50
        assign swatch_value      = 'url(' | append: image_url | append: ')'
        assign swatch_focal_point = value.swatch.image.presentation.focal_point
      elsif value.swatch.color
        assign swatch_value = 'rgb(' | append: value.swatch.color.rgb | append: ')'
      else
        assign swatch_value = null
      endif
    else
      if block.settings.swatch_source == 'variant'
        if value.variant.image
          assign color_variant_image = value.variant.image | image_url: width: 50
          assign swatch_value        = 'url(' | append: color_variant_image | append: ')'
        endif
      else
        # (din befintliga “custom swatch”-logik här…)
      endif
    endif

    # --- NY STOCK-LOGIK ---
    assign this_variant    = value.variant
    assign stock           = this_variant.inventory_quantity
    assign option_disabled = true
    if stock > 3
      assign option_disabled = false
    endif
  -%}

  {%- comment -%} Sätt “checked” på första tillgängliga variant {%- endcomment -%}
  {% assign is_checked = false %}
  {% if option_disabled == false %}
    {% if value.selected or has_set_default == false %}
      {% assign is_checked      = true %}
      {% assign has_set_default = true %}
    {% endif %}
  {% endif %}

  {%- capture input_id      -%}{{ section.id }}-{{ option.position }}-{{ forloop.index0 }}{%- endcapture -%}
  {%- capture input_name    -%}{{ option.name }}-{{ option.position }}{%- endcapture -%}
  {%- capture input_dataset -%}
    data-product-url="{{ value.product_url }}"
    data-option-value-id="{{ value.id }}"
  {%- endcapture -%}
  {%- capture label_unavailable -%}
    
      {{ 'products.product.variant_sold_out_or_unavailable' | t }}
    
  {%- endcapture -%}

  {%- if picker_type == 'swatch' -%}
    {%- capture help_text -%}
      {{ value | escape }}
      {{ label_unavailable }}
    {%- endcapture -%}
    {% render 'swatch-input',
      id:               input_id,
      name:             input_name,
      value:            value | escape,
      swatch:           value.swatch,
      product_form_id:  product_form_id,
      checked:          is_checked,
      visually_disabled: option_disabled,
      shape:            block.settings.swatch_type,
      source:           block.settings.swatch_source,
      option:           option,
      product:          product,
      help_text:        help_text,
      additional_props: input_dataset
    %}

  {%- elsif picker_type == 'button' -%}
    
    

  {%- elsif picker_type == 'dropdown' or picker_type == 'swatch_dropdown' -%}
    
  {%- endif -%}

{%- endfor -%}

Here is the modified product-variant-picker.liquid

{% comment %}
  Renders product variant-picker

  Accepts:
  - product: {Object} product object.
  - block: {Object} passing the block information.
  - product_form_id: {String} Id of the product form to which the variant picker is associated.

  Usage:
  {% render 'product-variant-picker', product: product, block: block, product_form_id: product_form_id %}
{% endcomment %}

{%- unless product.has_only_default_variant -%}
  
{%- endunless -%}

Here is the original product-variant-options.liquid

{% comment %}
  Renders product variant options

  Accepts:
  - product: {Object} product object.
  - option: {Object} current product_option object.
  - block: {Object} block object.
  - picker_type: {String} type of picker to dispay

  Usage:
  {% render 'product-variant-options',
    product: product,
    option: option,
    block: block
    picker_type: picker_type
  %}
{% endcomment %}
{%- liquid
  assign product_form_id = 'product-form-' | append: section.id
-%}

{%- for value in option.values -%}
  {%- liquid
    assign swatch_focal_point = null

    assign swatch_value = value | split: ' ' | last | handle 
    comment
      fall-back value ↑ or null?
    endcomment
    
    if block.settings.swatch_source == 'native'
      if value.swatch.image
        assign image_url = value.swatch.image | image_url: width: 50
        assign swatch_value = 'url(' | append: image_url | append: ')'
        assign swatch_focal_point = value.swatch.image.presentation.focal_point
      elsif value.swatch.color
        assign swatch_value = 'rgb(' | append: value.swatch.color.rgb | append: ')'
      else
        assign swatch_value = null
      endif
    else
      if block.settings.swatch_source == 'variant'
        if value.variant.image
          assign color_variant_image = value.variant.image | image_url: width: 50
          assign swatch_value = 'url(' | append: color_variant_image | append: ')'
        endif
      else
        assign swatch_file_extension = 'png'
        assign file_name_uniq = product.id | append: '_' | append: value | handle | append: '.' | append: swatch_file_extension
        assign file_name_custom = blank
        assign file_name_alt = value | handle | append: '.' | append: swatch_file_extension
        assign value_downcase = value | downcase
        assign swatch_config = settings.swatch_config | newline_to_br | split: '
'
        for swatch in swatch_config
          assign swatch_parts = swatch | strip | split: ':'
          assign swatch_name = swatch_parts.first | downcase | strip
          if swatch_name == value_downcase
            assign swatch_entry = swatch_parts.last | strip
            if swatch_entry contains '#'
              assign swatch_value = swatch_entry
              assign file_name_alt = blank
            else
              assign file_name_custom = swatch_entry
            endif
            break
          endif
        endfor
        assign file_name_final = blank
        if images[file_name_uniq] != blank
          assign file_name_final = file_name_uniq
        elsif file_name_custom != blank and images[file_name_custom] != blank 
          assign file_name_final = file_name_custom
        elsif images[file_name_alt] != blank
          assign file_name_final = file_name_alt
        endif
        assign swatch_image = blank
        if images[file_name_final] != blank
          assign swatch_image = images[file_name_final] | image_url: width: 50
        elsif file_name_final contains '//cdn.shopify.com/'
          assign swatch_image = file_name_final
        endif 
        if swatch_image != blank
          assign swatch_value = 'url(' | append: swatch_image | append: ')'
        endif
      endif
    endif

    assign option_disabled = true
    if value.available
      assign option_disabled = false
    endif
  -%}

  {%- capture input_id -%}
      {{ section.id }}-{{ option.position }}-{{ forloop.index0 -}}
    {%- endcapture -%}

  {%- capture input_name -%}
      {{ option.name }}-{{ option.position }}
    {%- endcapture -%}

  {%- capture input_dataset -%}
      data-product-url="{{ value.product_url }}"
      data-option-value-id="{{ value.id }}"
      {% if option_disabled %}data-crossout{% unless block.settings.enable_swatch_unavailable_click %} disabled{% endunless %}{% endif %}
    {%- endcapture -%}

  {%- capture label_unavailable -%}
      
        {{- 'products.product.variant_sold_out_or_unavailable' | t -}}
      
    {%- endcapture -%}

  {%- if picker_type == 'swatch' -%}
    {%- capture help_text -%}
      {{ value | escape }}
      {{ label_unavailable }}
    {%- endcapture -%}
    {%
      render 'swatch-input',
      id: input_id,
      name: input_name,
      value: value | escape,
      swatch: value.swatch,
      product_form_id: product_form_id,
      checked: value.selected,
      visually_disabled: option_disabled,
      shape: block.settings.swatch_type,
      source: block.settings.swatch_source,
      option: option,
      product: product,
      help_text: help_text,
      additional_props: input_dataset
    %}
  {%- elsif picker_type == 'button' -%}
    
    
  {%- elsif picker_type == 'dropdown' or picker_type == 'swatch_dropdown' -%}
    
  {%- endif -%}
{%- endfor -%}

Here comes the original product-variant-picker.liquid

{% comment %}
  Renders product variant-picker

  Accepts:
  - product: {Object} product object.
  - block: {Object} passing the block information.
  - product_form_id: {String} Id of the product form to which the variant picker is associated.
  Usage:
  {% render 'product-variant-picker', product: product, block: block, product_form_id: product_form_id %}
{% endcomment %}
{%- unless product.has_only_default_variant -%}
  
{%- endunless -%}

Could you please share your Store URL and password so that I take a look and provide you solution code.

Thanks

1 Like

Hi ScriptFlow! The store is open for now and here is URLto example product with variants https://doftnoter.se/products/parfym-damer-jil-sander-jil-sander-edp-n%C2%BA-4?variant=50637438058839

I approached it differently. Instead of disabling the variant buttons for items with low stock, I chose to hide them. That way, the add-to-cart functionality etc. wasn’t affected. So case closed.