{"record":{"id":"f48304447d2c09e7","repo":"Shopify/liquid","slug":"errors-syntax-unexpected-outer-tag-locale-tag","errorCode":null,"errorMessage":"errors.syntax.unexpected_outer_tag (locale: \"'{tag}' is not allowed outside of if or case blocks\")","messagePattern":"errors\\.syntax\\.unexpected_outer_tag \\(locale: \"'(.+?)' is not allowed outside of if or case blocks\"\\)","errorType":"exception","errorClass":"Liquid::SyntaxError","httpStatus":null,"severity":"error","filePath":"lib/liquid/document.rb","lineNumber":34,"sourceCode":"    end\n\n    def nodelist\n      @body.nodelist\n    end\n\n    def parse(tokenizer, parse_context)\n      while parse_body(tokenizer)\n      end\n      @body.freeze\n    rescue SyntaxError => e\n      e.line_number ||= parse_context.line_number\n      raise\n    end\n\n    def unknown_tag(tag, _markup, _tokenizer)\n      case tag\n      when 'else', 'end'\n        raise SyntaxError, parse_context.locale.t(\"errors.syntax.unexpected_outer_tag\", tag: tag)\n      else\n        raise SyntaxError, parse_context.locale.t(\"errors.syntax.unknown_tag\", tag: tag)\n      end\n    end\n\n    def render_to_output_buffer(context, output)\n      @body.render_to_output_buffer(context, output)\n    end\n\n    def render(context)\n      render_to_output_buffer(context, +'')\n    end\n\n    private\n\n    def new_body\n      parse_context.new_block_body\n    end","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/Shopify/liquid/blob/807d45a6b3d4568e64e86b375e3702df2c7c860c/lib/liquid/document.rb#L16-L52","documentation":"Document#unknown_tag raises a Liquid::SyntaxError with the localized message 'errors.syntax.unexpected_outer_tag' when an 'else' or 'end' tag is encountered at the document (top) level — i.e. outside any {% if %} or {% case %} block. The document parser has no open block to attach these tags to, so the template is malformed.","triggerScenarios":"Parsing (Template.parse) a template containing a top-level {% else %}, {% endif %}, {% endfor %}, {% endcase %}, etc., with no matching opening if/case block in scope.","commonSituations":"A stray {% endif %} left after deleting an {% if %}; unbalanced tags after manual edits; template concatenation that mixes fragments; broken split-tag logic in generated templates.","solutions":["Locate the orphaned {% else %}/{% end... %} tag and remove it or restore its matching opening block.","Recount open/close pairs for each block tag (if/case/for/unless/tablerow) in the template.","Use a template linter or parse-check templates in CI before deploy."],"exampleFix":"// before\n{% endif %}\nHello\n// after\n{% if condition %}\nHello\n{% endif %}","handlingStrategy":"validation","validationCode":"def balanced_block_tags?(src)\n  opens = src.scan(/\\{%-?\\s*(if|unless|case|for)\\b/).size\n  closes = src.scan(/\\{%-?\\s*end\\w+/).size\n  opens == closes && !src.match?(/\\{%-?\\s*else/)\nend","typeGuard":"def parseable_template?(src)\n  Liquid::Template.parse(src)\n  true\nrescue Liquid::SyntaxError\n  false\nend","tryCatchPattern":"begin\n  Liquid::Template.parse(src)\nrescue Liquid::SyntaxError => e\n  notify_author(\"Orphaned else/end tag: #{e.message}\")\nend","preventionTips":["Pair every if/case/for with its end tag; check counts in CI.","Never concatenate template fragments blindly.","Use a template linter that detects orphaned else/end tags.","Back up templates before manual edits."],"tags":["ruby","liquid","template-syntax","parse-error"],"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"}