Shopify/liquid · error · Liquid::UndefinedDropMethod

undefined method #

Error message

undefined method #{method}

What it means

Drop#liquid_method_missing raises Liquid::UndefinedDropMethod when a template invokes a method not defined/invokable on the Drop and strict_variables is enabled. Without strict_variables the miss silently returns nil; with it, Liquid surfaces the missing method as an error so typos are caught.

Solutions

  1. Fix the template to use an existing method/property on the drop.
  2. Add the missing method (or handle it in liquid_method_missing) on the drop class.
  3. If nil is acceptable, disable strict_variables for that render.
  4. Inspect self.class.invokable? to confirm which methods are exposed to templates.

Example fix

// before
class ProductDrop < Liquid::Drop
  def title; @product.title; end
end
// after
class ProductDrop < Liquid::Drop
  def title; @product.title; end
  def price; @product.price; end  # template uses {{ product.price }}
end
Defensive patterns

Strategy: type-guard

Validate before calling

def drop_exposes?(drop, method)
  drop.class.invokable?(method.to_sym)
end

Type guard

def safe_template_fields(drop_class)
  drop_class.instance_methods(false) # fields templates may reference
end

Try / catch

begin
  tpl.render(ctx, strict_variables: true)
rescue Liquid::UndefinedDropMethod => e
  logger.warn("Template referenced missing drop method: #{e.message}")
  tpl.render(ctx) # lenient re-render if nils acceptable
end

Prevention

When it happens

Trigger: Rendering with context.strict_variables = true (or Template.render(..., strict_variables: true)) while the template calls a property/method on a Drop that is neither defined on the class nor in its invokable set.

Common situations: Typo in a template field name on a drop-backed object; refactoring a drop class and removing a method still referenced by templates; enabling strict_variables in tests after developing with lenient nils.

Related errors


AI-assisted analysis of Shopify/liquid@807d45a6b3 (2026-09-08). Data as JSON: /api/errors/de40e83a4031328e. Report an issue: GitHub.

Appendix: source

Thrown at lib/liquid/drop.rb:35

  #     end
  #   end
  #
  #   tmpl = Liquid::Template.parse( ' {% for product in product.top_sales %} {{ product.name }} {%endfor%} '  )
  #   tmpl.render('product' => ProductDrop.new ) # will invoke top_sales query.
  #
  # Your drop can either implement the methods sans any parameters
  # or implement the liquid_method_missing(name) method which is a catch all.
  class Drop
    attr_writer :context

    def initialize
      @context = nil
    end

    # Catch all for the method
    def liquid_method_missing(method)
      return unless @context&.strict_variables
      raise Liquid::UndefinedDropMethod, "undefined method #{method}"
    end

    # called by liquid to invoke a drop
    def invoke_drop(method_or_key)
      if self.class.invokable?(method_or_key)
        send(method_or_key)
      else
        liquid_method_missing(method_or_key)
      end
    end

    def key?(_name)
      true
    end

    def inspect
      self.class.to_s
    end

View on GitHub (pinned to 807d45a6b3)