{"record":{"id":"531323bea0be29c5","repo":"Shopify/liquid","slug":"errors-syntax-cycle","errorCode":"errors.syntax.cycle","errorMessage":"options[:locale].t(\"errors.syntax.cycle\")","messagePattern":"options\\[:locale\\]\\.t\\(\"errors\\.syntax\\.cycle\"\\)","errorType":"exception","errorClass":"Liquid::SyntaxError","httpStatus":null,"severity":"error","filePath":"lib/liquid/tags/cycle.rb","lineNumber":64,"sourceCode":"\n      output << val\n\n      iteration += 1\n      iteration = 0 if iteration >= @variables.size\n\n      context.registers[:cycle][key] = iteration\n      output\n    end\n\n    private\n\n    # cycle [name:] expression(, expression)*\n    def strict2_parse(markup)\n      p = @parse_context.new_parser(markup)\n\n      @variables = []\n\n      raise SyntaxError, options[:locale].t(\"errors.syntax.cycle\") if p.look(:end_of_string)\n\n      first_expression = safe_parse_expression(p)\n      if p.look(:colon)\n        # cycle name: expr1, expr2, ...\n        @name = first_expression\n        @is_named = true\n        p.consume(:colon)\n        # After the colon, parse the first variable (required for named cycles)\n        @variables << maybe_dup_lookup(safe_parse_expression(p))\n      else\n        # cycle expr1, expr2, ...\n        @variables << maybe_dup_lookup(first_expression)\n      end\n\n      # Parse remaining comma-separated expressions\n      while p.consume?(:comma)\n        break if p.look(:end_of_string)\n","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/Shopify/liquid/blob/807d45a6b3d4568e64e86b375e3702df2c7c860c/lib/liquid/tags/cycle.rb#L46-L82","documentation":"The strict2_parse path for the `cycle` tag requires at least one expression: `cycle [name:] expression(, expression)*`. If the parser immediately sees end-of-string (empty markup), it raises SyntaxError with the localized 'errors.syntax.cycle'. This fires in strict error mode when a cycle tag has no arguments.","triggerScenarios":"`{% cycle %}` with empty markup under strict parsing; also a trailing comma like `{% cycle \"a\", %}` reaching end_of_string where an expression was expected.","commonSituations":"Templates generated programmatically with variables that interpolate to empty cycle arguments; strict error mode enabled in newer Liquid versions exposing previously tolerated lax markup; typos deleting the cycle values.","solutions":["Provide at least one expression: {% cycle \"odd\", \"even\" %}","Remove trailing commas after the last cycle value","Verify interpolated markup is non-empty before rendering the tag","Test templates under strict error_mode to catch these before production"],"exampleFix":"// before\n{% cycle %}\n// after\n{% cycle \"one\", \"two\", \"three\" %}","handlingStrategy":"validation","validationCode":"def valid_cycle_markup?(markup)\n  !markup.strip.empty? && !markup.strip.end_with?(',')\nend","typeGuard":null,"tryCatchPattern":"begin\n  Liquid::Template.parse(source)\nrescue Liquid::SyntaxError => e\n  raise \"cycle tag needs at least one value: #{e.message}\"\nend","preventionTips":["Provide at least one expression in every cycle tag","Avoid trailing commas in cycle argument lists","Validate interpolated markup is non-empty before render"],"tags":["liquid","ruby","template-syntax","cycle-tag"],"backgroundTag":"liquid-tag-syntax-error","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"}