Shopify/liquid · error · Liquid::TemplateEncodingError
errors.syntax.invalid_template_encoding
errors.syntax.invalid_template_encoding
Error message
parse_context.locale.t("errors.syntax.invalid_template_encoding") What it means
Template#parse validates the encoding of the source string before tokenizing. If source.valid_encoding? is false it raises Liquid::TemplateEncodingError with the localized errors.syntax.invalid_template_encoding message, because Liquid cannot tokenize bytes that do not form valid text in the string's declared encoding.
Solutions
- Re-encode the source before parsing: source.encode(Encoding::UTF_8, invalid: :replace, undef: :replace).
- Read template files with the correct encoding: File.read(path, encoding: 'UTF-8') or force_encoding when the true encoding is known.
- Fix the upstream data source so stored template bytes match their declared encoding.
Example fix
// before
Liquid::Template.parse(File.binread('template.liquid'))
// after
source = File.read('template.liquid', encoding: 'UTF-8')
Liquid::Template.parse(source.valid_encoding? ? source : source.encode(Encoding::UTF_8, invalid: :replace, undef: :replace)) Defensive patterns
Strategy: validation
Validate before calling
source = source.to_s raise Liquid::TemplateEncodingError, 'invalid encoding' unless source.valid_encoding?
Type guard
def valid_template_source?(str) str.is_a?(String) && str.valid_encoding? end
Try / catch
begin Liquid::Template.parse(source) rescue Liquid::TemplateEncodingError => e source = source.dup.force_encoding(Encoding::UTF_8).scrub retry end
Prevention
- Always read template files with explicit UTF-8 encoding
- Scrub user-supplied source before parsing
- Normalize database-stored templates to UTF-8
When it happens
Trigger: Calling Liquid::Template.parse with a String whose encoding label (e.g. UTF-8) does not match its actual bytes — typically binary data read as UTF-8, or files written in another encoding (ISO-8859-1, UTF-16) but tagged UTF-8.
Common situations: Reading template files without specifying encoding on systems with non-UTF-8 locale; concatenating binary attachments into template source; database columns storing non-UTF-8 bytes.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Invalid byte sequence in #
- invalid byte sequence in #
- Invalid byte sequence in #
- invalid base64 provided to base64_decode
- invalid base64 provided to base64_url_safe_decode
AI-assisted analysis of Shopify/liquid@807d45a6b3 (2026-09-08).
Data as JSON: /api/errors/b20204c20def6494.
Report an issue: GitHub.
Appendix: source
Thrown at lib/liquid/template.rb:103
environment = options[:environment] || Environment.default
new(environment: environment).parse(source, options)
end
end
def initialize(environment: Environment.default)
@environment = environment
@rethrow_errors = false
@resource_limits = ResourceLimits.new(environment.default_resource_limits)
end
# Parse source code.
# Returns self for easy chaining
def parse(source, options = {})
parse_context = configure_options(options)
source = source.to_s.to_str
unless source.valid_encoding?
raise TemplateEncodingError, parse_context.locale.t("errors.syntax.invalid_template_encoding")
end
tokenizer = parse_context.new_tokenizer(source, start_line_number: @line_numbers && 1)
@root = Document.parse(tokenizer, parse_context)
self
end
def registers
@registers ||= {}
end
def assigns
@assigns ||= {}
end
def instance_assigns
@instance_assigns ||= {}
endView on GitHub (pinned to 807d45a6b3)