{"record":{"id":"2c837633fa0de879","repo":"Shopify/liquid","slug":"errors-syntax-unexpected-else-locale-unexpected","errorCode":null,"errorMessage":"errors.syntax.unexpected_else (locale: Unexpected 'else' without matching if/case tag in 'block_name')","messagePattern":"errors\\.syntax\\.unexpected_else \\(locale: Unexpected 'else' without matching if/case tag in 'block_name'\\)","errorType":"exception","errorClass":"Liquid::SyntaxError","httpStatus":null,"severity":"error","filePath":"lib/liquid/block.rb","lineNumber":39,"sourceCode":"      @body.render(context)\n    end\n\n    def blank?\n      @blank\n    end\n\n    def nodelist\n      @body.nodelist\n    end\n\n    def unknown_tag(tag_name, _markup, _tokenizer)\n      Block.raise_unknown_tag(tag_name, block_name, block_delimiter, parse_context)\n    end\n\n    # @api private\n    def self.raise_unknown_tag(tag, block_name, block_delimiter, parse_context)\n      if tag == 'else'\n        raise SyntaxError, parse_context.locale.t(\n          \"errors.syntax.unexpected_else\",\n          block_name: block_name,\n        )\n      elsif tag.start_with?('end')\n        raise SyntaxError, parse_context.locale.t(\n          \"errors.syntax.invalid_delimiter\",\n          tag: tag,\n          block_name: block_name,\n          block_delimiter: block_delimiter,\n        )\n      else\n        raise SyntaxError, parse_context.locale.t(\"errors.syntax.unknown_tag\", tag: tag)\n      end\n    end\n\n    def raise_tag_never_closed(block_name)\n      raise SyntaxError, parse_context.locale.t(\"errors.syntax.tag_never_closed\", block_name: block_name)\n    end","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/Shopify/liquid/blob/807d45a6b3d4568e64e86b375e3702df2c7c860c/lib/liquid/block.rb#L21-L57","documentation":"Liquid raises this SyntaxError when an `{% else %}` (or `{% elsif %}`) tag appears without an open `{% if %}`, `{% case %}`, or `{% unless %}` block to match. Block.raise_unknown_tag intercepts every `else`-family unknown tag and reports which block type the parser was inside (block_name), so a stray else fails at parse time rather than silently rendering.","triggerScenarios":"Writing `{% else %}` in a template with no enclosing if/case/unless; nesting blocks so an else pairs with the wrong open block; using `{% else %}` inside a custom block tag that does not declare an else delimiter; typos that unclosed the real if (e.g. `{% ify %}`).","commonSituations":"Copy-pasting template fragments out of context; refactoring that removes or renames an `{% if %}` while keeping its `{% else %}`; custom tag authors passing the wrong block_name/delimiter to parse_body; templates split across includes where the if lives in the parent.","solutions":["Add or restore the matching `{% if %}`/`{% case %}`/`{% unless %}` opening tag before the `{% else %}`.","Check nesting so the `{% else %}` belongs to the nearest open block — count opens/closes in the template.","If the else is meant to be standalone output, escape it or remove it.","For custom block tags, register 'else' in the tag markup or pass the correct block_delimiter so parse accepts it."],"exampleFix":"// before\n{% else %}\n  fallback\n{% endif %}\n// after\n{% if available %}\n  content\n{% else %}\n  fallback\n{% endif %}","handlingStrategy":"validation","validationCode":"def else_balanced?(src)\n  opens = src.scan(/{%-?\\s*(if|case|unless)\\b/).size\n  elses = src.scan(/{%-?\\s*(else|elsif)\\b/).size\n  closes = src.scan(/{%-?\\s*end(if|case|unless)?\\b/).size\n  opens >= 1 && elses <= opens\nend","typeGuard":"null","tryCatchPattern":"begin\n  Liquid::Template.parse(src)\nrescue Liquid::SyntaxError => e\n  logger.warn(\"liquid syntax: #{e.message}\")\n  fallback_template\nend","preventionTips":["Always write the if/else/endif skeleton first, then fill in branches.","Use an editor with Liquid syntax highlighting and bracket matching.","Parse templates in CI before deploying.","Avoid copy-pasting partial branches without their opening block."],"tags":["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"}