Shopify/liquid · error · Liquid::ArgumentError
e.message (re-raised as Liquid::ArgumentError from…
Error message
e.message (re-raised as Liquid::ArgumentError from ::ArgumentError during operator invocation)
What it means
When a comparison operator is applied via `left.send(operation, right)` and Ruby raises ::ArgumentError, Liquid re-raises it as Liquid::ArgumentError carrying the original message. This happens when an object's operator method (e.g. <=>, ==, a custom method) rejects the right operand's type, or the object misuses its own API internally.
Solutions
- Fix the comparison in the template so both sides share a type (e.g. compare numbers to numbers).
- Coerce values before comparison via a filter or by assigning normalized variables.
- If you own a custom drop/object, correct its operator implementation or arity.
- Wrap render in error handling to log e.message and identify the offending method.
Example fix
// before
{% if price > "100" %}...{% endif %}
// after
{% assign limit = 100 %}
{% if price > limit %}...{% endif %} Defensive patterns
Strategy: type-guard
Validate before calling
def comparable?(a, b) (a.is_a?(Numeric) && b.is_a?(Numeric)) || (a.is_a?(String) && b.is_a?(String)) end # guard template conditions: only compare same-typed values
Type guard
def safe_compare(left, right, op) return false unless left.respond_to?(op) && right.respond_to?(op) return false unless left.class == right.class || (left.is_a?(Numeric) && right.is_a?(Numeric)) true end
Try / catch
begin
html = template.render(assigns)
rescue Liquid::ArgumentError => e
logger.warn("liquid comparison failed: #{e.message}")
html = template.render(normalized_assigns)
end Prevention
- Normalize variable types (numbers vs strings) before comparing in templates.
- Implement <=>/== correctly in custom drops.
- Avoid comparing nil or formatted (locale) strings as numbers.
- Test templates with representative render data.
When it happens
Trigger: Comparing incompatible types in `{% if x > y %}` (e.g. String vs Integer with a String#> that raises); custom drop/objects defining operators that raise ArgumentError; using an operator name that resolves to a method with wrong arity; non-Hash operands where left/right both respond_to? the operator.
Common situations: Comparing nil-wrapped values or strings that look numeric; custom Liquid drops with badly implemented <=> or respond_to?; template conditions on locale-formatted numbers; upgrading Ruby changing operator semantics.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- cannot sort values of incompatible types
- errors.argument.include
- Expected Hash or Liquid::Context as parameter
- cannot select the property '#
- invalid integer
AI-assisted analysis of Shopify/liquid@807d45a6b3 (2026-09-08).
Data as JSON: /api/errors/7a7a45e7658e35b7.
Report an issue: GitHub.
Appendix: source
Thrown at lib/liquid/condition.rb:194
def interpret_condition(left, right, op, context)
# If the operator is empty this means that the decision statement is just
# a single variable. We can just poll this variable from the context and
# return this as the result.
return context.evaluate(left) if op.nil?
left = Liquid::Utils.to_liquid_value(context.evaluate(left))
right = Liquid::Utils.to_liquid_value(context.evaluate(right))
operation = self.class.operators[op] || raise(Liquid::ArgumentError, "Unknown operator #{op}")
if operation.respond_to?(:call)
operation.call(self, left, right)
elsif left.respond_to?(operation) && right.respond_to?(operation) && !left.is_a?(Hash) && !right.is_a?(Hash)
begin
left.send(operation, right)
rescue ::ArgumentError => e
raise Liquid::ArgumentError, e.message
end
end
end
def deprecated_default_context
warn("DEPRECATION WARNING: Condition#evaluate without a context argument is deprecated " \
"and will be removed from Liquid 6.0.0.")
Context.new
end
class ParseTreeVisitor < Liquid::ParseTreeVisitor
def children
[
@node.left,
@node.right,
@node.child_condition,
@node.attachment
].compactView on GitHub (pinned to 807d45a6b3)