{"record":{"id":"b20204c20def6494","repo":"Shopify/liquid","slug":"errors-syntax-invalid-template-encoding","errorCode":"errors.syntax.invalid_template_encoding","errorMessage":"parse_context.locale.t(\"errors.syntax.invalid_template_encoding\")","messagePattern":"parse_context\\.locale\\.t\\(\"errors\\.syntax\\.invalid_template_encoding\"\\)","errorType":"exception","errorClass":"Liquid::TemplateEncodingError","httpStatus":null,"severity":"error","filePath":"lib/liquid/template.rb","lineNumber":103,"sourceCode":"        environment = options[:environment] || Environment.default\n        new(environment: environment).parse(source, options)\n      end\n    end\n\n    def initialize(environment: Environment.default)\n      @environment = environment\n      @rethrow_errors  = false\n      @resource_limits = ResourceLimits.new(environment.default_resource_limits)\n    end\n\n    # Parse source code.\n    # Returns self for easy chaining\n    def parse(source, options = {})\n      parse_context = configure_options(options)\n      source = source.to_s.to_str\n\n      unless source.valid_encoding?\n        raise TemplateEncodingError, parse_context.locale.t(\"errors.syntax.invalid_template_encoding\")\n      end\n\n      tokenizer     = parse_context.new_tokenizer(source, start_line_number: @line_numbers && 1)\n      @root         = Document.parse(tokenizer, parse_context)\n      self\n    end\n\n    def registers\n      @registers ||= {}\n    end\n\n    def assigns\n      @assigns ||= {}\n    end\n\n    def instance_assigns\n      @instance_assigns ||= {}\n    end","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/Shopify/liquid/blob/807d45a6b3d4568e64e86b375e3702df2c7c860c/lib/liquid/template.rb#L85-L121","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nLiquid::Template.parse(File.binread('template.liquid'))\n// after\nsource = File.read('template.liquid', encoding: 'UTF-8')\nLiquid::Template.parse(source.valid_encoding? ? source : source.encode(Encoding::UTF_8, invalid: :replace, undef: :replace))","handlingStrategy":"validation","validationCode":"source = source.to_s\nraise Liquid::TemplateEncodingError, 'invalid encoding' unless source.valid_encoding?","typeGuard":"def valid_template_source?(str)\n  str.is_a?(String) && str.valid_encoding?\nend","tryCatchPattern":"begin\n  Liquid::Template.parse(source)\nrescue Liquid::TemplateEncodingError => e\n  source = source.dup.force_encoding(Encoding::UTF_8).scrub\n  retry\nend","preventionTips":["Always read template files with explicit UTF-8 encoding","Scrub user-supplied source before parsing","Normalize database-stored templates to UTF-8"],"tags":["liquid","encoding","utf-8","template-parse"],"backgroundTag":"invalid-argument-format","analyzedSha":"807d45a6b3d4568e64e86b375e3702df2c7c860c","analyzedAt":"2026-09-08T11:31:38.917Z","contentChangedAt":"2026-09-08T11:31:38.917Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}