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
- Fix the template to use an existing method/property on the drop.
- Add the missing method (or handle it in liquid_method_missing) on the drop class.
- If nil is acceptable, disable strict_variables for that render.
- 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
- Run template test suites with strict_variables: true to catch typos.
- Keep drop methods and template fields in sync when refactoring.
- Document each drop's exposed interface.
- Prefer defining explicit methods over relying on method_missing.
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
- Nesting too deep
- errors.syntax.unexpected_outer_tag
- errors.syntax.unknown_tag (locale: 'Unknown tag 'tag'')
- This liquid context does not allow includes.
- No such template '#
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
endView on GitHub (pinned to 807d45a6b3)