Shopify/liquid · error · Liquid::SyntaxError
errors.syntax.unknown_tag (locale: 'Unknown tag 'tag'')
Error message
errors.syntax.unknown_tag (locale: 'Unknown tag 'tag'')
What it means
Liquid raises this SyntaxError when the parser encounters a tag it has no registered handler for and which is neither `else` nor an `end...` delimiter. It is the catch-all unknown-tag path in Block.raise_unknown_tag, thrown at parse time with the offending tag name interpolated.
Solutions
- Fix the tag name typo, or remove the tag if it's not needed.
- Register the custom tag: `Liquid::Template.register_tag('mytag', MyTag)` before parsing.
- Check Liquid version docs — the tag may not exist in your version or may require an extension gem.
- If it's a closer, make sure it uses the correct `end...` spelling so it routes to the delimiter check instead.
Example fix
// before
Liquid::Template.parse("{% prices %}...") # unknown tag
// after
class PricesTag < Liquid::Tag; end
Liquid::Template.register_tag('prices', PricesTag)
Liquid::Template.parse("{% prices %}...") Defensive patterns
Strategy: validation
Validate before calling
KNOWN = Liquid::Template.tags.keys
unknown = src.scan(/{%-?\s*(\w+)/).flatten.uniq - KNOWN - %w[else elsif endraw]
unknown.each { |t| puts "unknown tag: #{t}" } Type guard
null
Try / catch
begin
Liquid::Template.parse(src)
rescue Liquid::SyntaxError => e
if e.message.include?('Unknown tag')
logger.error("unknown liquid tag: #{e.message}")
nil
else
raise
end
end Prevention
- Register all custom tags at boot, before any parse call.
- Check tag availability per Liquid version / platform (Shopify vs vanilla).
- Keep a whitelist of allowed tags when accepting user templates.
- Autocomplete-enabled editors reduce typos.
When it happens
Trigger: Misspelled tag names like `{% ifx %}`; using a tag from another Liquid dialect (e.g. Shopify-only or Jekyll-only tags in plain Liquid); forgetting `require 'liquid/tag'` registration for a custom tag; tag names that don't start with 'end' but are meant as closers.
Common situations: Porting Shopify themes to a plain-Liquid gem; upgrading/downgrading Liquid where a tag was added or removed; custom tags defined after rendering starts or in the wrong namespace; typos in tag names.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- errors.syntax.unexpected_else (locale: Unexpected 'else'…
- errors.syntax.invalid_delimiter
- errors.syntax.tag_never_closed
- errors.syntax.tag_termination
- errors.syntax.variable_termination
AI-assisted analysis of Shopify/liquid@807d45a6b3 (2026-09-08).
Data as JSON: /api/errors/652f0574a100e9f4.
Report an issue: GitHub.
Appendix: source
Thrown at lib/liquid/block.rb:51
Block.raise_unknown_tag(tag_name, block_name, block_delimiter, parse_context)
end
# @api private
def self.raise_unknown_tag(tag, block_name, block_delimiter, parse_context)
if tag == 'else'
raise SyntaxError, parse_context.locale.t(
"errors.syntax.unexpected_else",
block_name: block_name,
)
elsif tag.start_with?('end')
raise SyntaxError, parse_context.locale.t(
"errors.syntax.invalid_delimiter",
tag: tag,
block_name: block_name,
block_delimiter: block_delimiter,
)
else
raise SyntaxError, parse_context.locale.t("errors.syntax.unknown_tag", tag: tag)
end
end
def raise_tag_never_closed(block_name)
raise SyntaxError, parse_context.locale.t("errors.syntax.tag_never_closed", block_name: block_name)
end
def block_name
@tag_name
end
def block_delimiter
@block_delimiter ||= "end#{block_name}"
end
private
# @api publicView on GitHub (pinned to 807d45a6b3)