Shopify/liquid · error · Liquid::SyntaxError
errors.syntax.capture
errors.syntax.capture
Error message
options[:locale].t("errors.syntax.capture") What it means
The `capture` tag stores rendered output into a variable, so its markup must match Capture::Syntax (a valid variable name). In lax_parse (also used by strict_parse), if the markup does not match, Liquid raises SyntaxError with the localized message 'errors.syntax.capture'. Parsing aborts before any rendering.
Solutions
- Give the capture tag exactly one variable name: {% capture greeting %}...{% endcapture %}
- Remove '=' or dotted assignment targets from the capture markup; capture only takes a plain name
- If you need assignment of an expression instead of block output, use {% assign var = expr %}
- Lint templates before deploy to catch malformed capture tags
Example fix
// before
{% capture "headline" %}{{ title | upcase }}{% endcapture %}
// after
{% capture headline %}{{ title | upcase }}{% endcapture %} Defensive patterns
Strategy: validation
Validate before calling
def valid_capture_markup?(markup) markup =~ /\A[\w\-\.]+\z/ end
Try / catch
begin Liquid::Template.parse(source) rescue Liquid::SyntaxError => e raise TemplateSyntaxError.new(source: source, cause: e) end
Prevention
- Capture takes exactly one plain variable name — no quotes, '=' or assignments
- Use assign for expression assignment, capture for block output
- Lint templates before deployment
When it happens
Trigger: {% capture %} with empty markup, or markup that is not a single variable name, e.g. `{% capture foo.bar = x %}` or `{% capture "name" %}`.
Common situations: Hand-edited theme templates; copying capture blocks and mangling the variable name; templates generated by string concatenation losing the variable argument; beginners writing `{% capture greeting %}Hello{% endcapture %}` variants with punctuation in the name.
Related errors
- errors.syntax.unexpected_outer_tag
- errors.syntax.unknown_tag (locale: 'Unknown tag 'tag'')
- errors.syntax.assign
- errors.syntax.case
- errors.syntax.case_invalid_when
AI-assisted analysis of Shopify/liquid@807d45a6b3 (2026-09-08).
Data as JSON: /api/errors/ab28311155ff799b.
Report an issue: GitHub.
Appendix: source
Thrown at lib/liquid/tags/capture.rb:38
# @liquid_syntax_keyword variable The name of the variable being created.
# @liquid_syntax_keyword value The value you want to assign to the variable.
class Capture < Block
include ParserSwitching
Syntax = /(#{VariableSignature}+)/o
attr_reader :to
def initialize(tag_name, markup, options)
super
parse_with_selected_parser(markup)
end
def lax_parse(markup)
if markup =~ Syntax
@to = Regexp.last_match(1)
else
raise SyntaxError, options[:locale].t("errors.syntax.capture")
end
end
def strict_parse(markup)
lax_parse(markup)
end
def strict2_parse(markup)
p = @parse_context.new_parser(markup.strip)
@to = p.consume(:id)
p.consume(:end_of_string)
end
def render_to_output_buffer(context, output)
context.resource_limits.with_capture do
capture_output = render(context)
context.scopes.last[@to] = capture_output
endView on GitHub (pinned to 807d45a6b3)