{"record":{"id":"b27faefa8edb4efa","repo":"Shopify/liquid","slug":"expected-hash-or-liquid-context-as-parameter","errorCode":null,"errorMessage":"Expected Hash or Liquid::Context as parameter","messagePattern":"Expected Hash or Liquid::Context as parameter","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/liquid/template.rb","lineNumber":163,"sourceCode":"      when Liquid::Context\n        c = args.shift\n\n        if @rethrow_errors\n          c.exception_renderer = Liquid::RAISE_EXCEPTION_LAMBDA\n        end\n\n        c\n      when Liquid::Drop\n        drop = args.shift\n        c    = Context.new([drop, assigns], instance_assigns, registers, @rethrow_errors, @resource_limits, {}, @environment)\n        drop.context = c if drop.respond_to?(:context=)\n        c\n      when Hash\n        Context.new([args.shift, assigns], instance_assigns, registers, @rethrow_errors, @resource_limits, {}, @environment)\n      when nil\n        Context.new(assigns, instance_assigns, registers, @rethrow_errors, @resource_limits, {}, @environment)\n      else\n        raise ArgumentError, \"Expected Hash or Liquid::Context as parameter\"\n      end\n\n      output = nil\n\n      case args.last\n      when Hash\n        options = args.pop\n        output  = options[:output] if options[:output]\n        static_registers = context.registers.static\n\n        options[:registers]&.each do |key, register|\n          static_registers[key] = register\n        end\n\n        apply_options_to_context(context, options)\n      when Module, Array\n        context.add_filters(args.pop)\n      end","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/Shopify/liquid/blob/807d45a6b3d4568e64e86b375e3702df2c7c860c/lib/liquid/template.rb#L145-L181","documentation":"Template#render accepts an optional first argument that must be a Hash of assigns, a Liquid::Context, or nil. Any other type (String, Array, integer, etc.) raises ArgumentError with 'Expected Hash or Liquid::Context as parameter'.","triggerScenarios":"Calling template.render('foo'), template.render(assigns_array), or template.render(some_object) where the first argument is neither Hash, Liquid::Context, nor omitted/nil.","commonSituations":"Passing a JSON string of variables instead of a parsed Hash; passing OpenStruct/dry structs as assigns; refactoring from render! to render while changing argument shapes; tests (e.g. test_internal_error_is_raised_with_template_name) exercising bad arguments.","solutions":["Convert the argument to a Hash before rendering: template.render(JSON.parse(json)).","Pass variables inside a Hash: template.render('key' => value) or use template.assignments/instance assigns.","If sharing state across renders, construct and pass a Liquid::Context explicitly.","Pass nothing (or nil) when no outer assigns are needed."],"exampleFix":"// before\ntemplate.render('{\"user\": \"bob\"}')\n// after\ntemplate.render(JSON.parse('{\"user\": \"bob\"}'))","handlingStrategy":"type-guard","validationCode":"raise ArgumentError, 'assigns must be a Hash' unless arg.nil? || arg.is_a?(Hash) || arg.is_a?(Liquid::Context)","typeGuard":"def valid_render_arg?(arg)\n  arg.nil? || arg.is_a?(Hash) || arg.is_a?(Liquid::Context)\nend","tryCatchPattern":"begin\n  template.render(assigns)\nrescue ArgumentError => e\n  raise e unless e.message.include?('Expected Hash or Liquid::Context')\n  template.render(assigns.to_h)\nend","preventionTips":["Always pass a Hash or Liquid::Context as the first render argument","Parse JSON strings before using them as assigns","Wrap custom assign objects with #to_h at the call site"],"tags":["liquid","argument-error","type-mismatch","render"],"backgroundTag":"invalid-argument-value","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"}