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

  1. Fix the tag name typo, or remove the tag if it's not needed.
  2. Register the custom tag: `Liquid::Template.register_tag('mytag', MyTag)` before parsing.
  3. Check Liquid version docs — the tag may not exist in your version or may require an extension gem.
  4. 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

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


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 public

View on GitHub (pinned to 807d45a6b3)