{"record":{"id":"2b0890e5437a723c","repo":"Shopify/liquid","slug":"expected-type-but-found-tokens-p-first","errorCode":null,"errorMessage":"Expected #{type} but found #{@tokens[@p].first}","messagePattern":"Expected #(.+?) but found #(.+?)","errorType":"exception","errorClass":"Liquid::SyntaxError","httpStatus":null,"severity":"error","filePath":"lib/liquid/parser.rb","lineNumber":19,"sourceCode":"# frozen_string_literal: true\n\nmodule Liquid\n  class Parser\n    def initialize(input, reject_bare_brackets: false)\n      ss = input.is_a?(StringScanner) ? input : StringScanner.new(input)\n      @tokens = Lexer.tokenize(ss)\n      @p      = 0 # pointer to current location\n      @reject_bare_brackets = reject_bare_brackets\n    end\n\n    def jump(point)\n      @p = point\n    end\n\n    def consume(type = nil)\n      token = @tokens[@p]\n      if type && token[0] != type\n        raise SyntaxError, \"Expected #{type} but found #{@tokens[@p].first}\"\n      end\n      @p += 1\n      token[1]\n    end\n\n    # Only consumes the token if it matches the type\n    # Returns the token's contents if it was consumed\n    # or false otherwise.\n    def consume?(type)\n      token = @tokens[@p]\n      return false unless token && token[0] == type\n      @p += 1\n      token[1]\n    end\n\n    # Like consume? Except for an :id token of a certain name\n    def id?(str)\n      token = @tokens[@p]","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/Shopify/liquid/blob/807d45a6b3d4568e64e86b375e3702df2c7c860c/lib/liquid/parser.rb#L1-L37","documentation":"Liquid::Parser#consume raises Liquid::SyntaxError when the next token's type does not match the expected type (or when a specific type was requested but the token stream has something else). It signals malformed Liquid syntax during expression parsing, e.g. inside variables or variable_lookups.","triggerScenarios":"A template expression like {{ product. }} or {{ a[ }} where an identifier, dot, or closing bracket is expected but a different token (or end of stream) is found; malformed range or argument syntax.","commonSituations":"Typo in a template (missing variable name after a dot); copy-pasted broken Liquid; dynamically generated templates with string interpolation errors; unclosed brackets.","solutions":["Fix the Liquid template so the expected token is present (e.g. complete the identifier after the dot)","Validate templates with Liquid::Template.parse in a test/CI step to catch syntax errors early","Check for missing or extra dots, brackets, and pipes in the failing expression"],"exampleFix":"<!-- before -->\n{{ product. }}\n<!-- after -->\n{{ product.title }}","handlingStrategy":"validation","validationCode":"def valid_liquid?(tpl)\n  Liquid::Template.parse(tpl)\n  true\nrescue Liquid::SyntaxError\n  false\nend","typeGuard":null,"tryCatchPattern":"begin\n  Liquid::Template.parse(template_source)\nrescue Liquid::SyntaxError => e\n  logger.warn(\"Liquid syntax error: #{e.message}\")\nend","preventionTips":["Lint templates in CI with Liquid::Template.parse","Avoid hand-editing expressions with dots/brackets without validation","Render test fixtures for every template"],"tags":["liquid","template-engine","syntax-error","parser"],"backgroundTag":"schema-validation-failed","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"}