spree/spree · warning

Spree::Variant#additional_images is deprecated and will be r

Error message

Spree::Variant#additional_images is deprecated and will be removed in Spree 6.1. Use #gallery_media instead.

What it means

Variant#additional_images returned the gallery minus the primary image for thumbnail strips. 6.0 drops it as a presentation concern — the deprecated shell delegates to gallery_media.reject { |m| m.id == primary_media&.id }, warns per call, and is removed in 6.1. Nothing in Spree calls it.

Source

Thrown at spree/core/app/models/spree/variant.rb:474

      update_column(:primary_media_id, first_media&.id)
    end

    # @deprecated Read #gallery_media directly; removed in 6.1. Nothing in
    #   Spree calls this — a hover image is a storefront presentation choice,
    #   not something core should name.
    # @return [Spree::Media, nil]
    def secondary_image
      Spree::Deprecation.warn('Spree::Variant#secondary_image is deprecated and will be removed in Spree 6.1. Use #gallery_media instead.')
      gallery_media.second
    end

    # @deprecated Read #gallery_media directly; removed in 6.1. Nothing in
    #   Spree calls this, and which images to show beside the main one is a
    #   storefront presentation choice.
    # @return [Array<Spree::Media>]
    def additional_images
      Spree::Deprecation.warn('Spree::Variant#additional_images is deprecated and will be removed in Spree 6.1. Use #gallery_media instead.')
      gallery_media.reject { |media| media.id == primary_media&.id }
    end

    # Returns an array of hashes with the option type name, value and presentation
    # @return [Array<Hash>]
    def options
      @options ||= option_values.
                   includes(option_type: :product_option_types).
                   merge(product.product_option_types).
                   reorder('spree_product_option_types.position').
                   map do |option_value|
                     {
                       name: option_value.option_type.name,
                       value: option_value.name,
                       presentation: option_value.presentation
                     }
                   end
    end

View on GitHub (pinned to 06bf66a868)

Solutions

  1. Compute it in your view/presenter: variant.gallery_media.reject { |m| m.id == variant.primary_media&.id }.
  2. Or simply iterate variant.gallery_media and skip the primary in the template — own the exclusion rule.
  3. Cache the reject in a local variable when used multiple times per card.
  4. Update theme gems to Spree 6-compatible releases.

Example fix

# before
variant.additional_images.each { |image| ... }

# after
variant.gallery_media.reject { |m| m.id == variant.primary_media&.id }.each { |image| ... }
Defensive patterns

Strategy: fallback

Validate before calling

thumbs = if variant.respond_to?(:gallery_media)
  variant.gallery_media.reject { |m| m.id == variant.primary_media&.id }
else
  variant.additional_images
end

Prevention

When it happens

Trigger: Storefront gallery partials calling variant.additional_images to render thumbnails beside the main image.

Common situations: Themes and gallery components written for Spree 5.x; code that assumed the exclusion rule (primary excluded) lives in core.

Related errors


AI-assisted analysis of spree/spree@06bf66a868 (2026-08-21). Data as JSON: /api/errors/350e629422e35159. Report an issue: GitHub.