{"record":{"id":"096167daf9978af0","repo":"SeleniumHQ/selenium","slug":"button-must-be-a-positive-integer-or-one-of-butt","errorCode":null,"errorMessage":"button must be a positive integer or one of #{BUTTONS.keys}, not #{button.class}","messagePattern":"button must be a positive integer or one of #(.+?), not #(.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"rb/lib/selenium/webdriver/common/interactions/pointer_press.rb","lineNumber":73,"sourceCode":"\n        private\n\n        def assert_source(source)\n          raise TypeError, \"#{source.type} is not a valid input type\" unless source.is_a? PointerInput\n        end\n\n        def assert_button(button)\n          case button\n          when Symbol\n            raise ArgumentError, \"#{button} is not a valid button!\" unless BUTTONS.key? button\n\n            BUTTONS[button]\n          when Integer\n            raise ArgumentError, 'Button number cannot be negative!' if button.negative?\n\n            button\n          else\n            raise TypeError, \"button must be a positive integer or one of #{BUTTONS.keys}, not #{button.class}\"\n          end\n        end\n\n        def assert_direction(direction)\n          raise ArgumentError, \"#{direction.inspect} is not a valid button direction\" unless DIRECTIONS.key? direction\n\n          DIRECTIONS[direction]\n        end\n      end # PointerPress\n    end # Interactions\n  end # WebDriver\nend # Selenium\n","sourceCodeStart":55,"sourceCodeEnd":86,"githubUrl":"https://github.com/SeleniumHQ/selenium/blob/aa36b38e696a0909e973bdf5e2f9031ffe842c4b/rb/lib/selenium/webdriver/common/interactions/pointer_press.rb#L55-L86","documentation":"Raised as TypeError by PointerPress#assert_button when button is neither a Symbol nor an Integer (the case/else branch). The message lists the accepted Symbol keys (BUTTONS.keys) and notes an Integer is also valid, then shows the offending value's class.","triggerScenarios":"Passing pointer_down/pointer_up (or PointerPress.new) a value of an unsupported type: a String ('left'), a Float (0.0), nil, or an Object. The case statement only matches Symbol and Integer.","commonSituations":"Reading a button from JSON/YAML config as a string and not converting; passing nil where a button is required; mixing Float (0.0) with Integer expectations.","solutions":["Pass a Symbol (:left/:middle/:right/...) or a non-negative Integer.","Coerce from config: button = config_string.match?(/^\\d+$/) ? config_string.to_i : config_string.to_sym, then verify it is accepted."],"exampleFix":"# before\ndriver.action.pointer_down('left').perform # => TypeError: button must be a positive integer or one of [:left, ...], not String\n\n# after\ndriver.action.pointer_down(:left).perform","handlingStrategy":"type-guard","validationCode":"case button\nwhen String then button = button.match?(/\\A-?\\d+\\z/) ? button.to_i : button.to_sym\nwhen Float then button = button.to_i\nend\ndriver.action.pointer_down(button).perform","typeGuard":"def button_arg?(b)\n  b.is_a?(Symbol) || (b.is_a?(Integer) && !b.negative?)\nend","tryCatchPattern":null,"preventionTips":["Pass a Symbol or a non-negative Integer only — never a String, Float, or nil.","Coerce config-derived button values (String) to Symbol/Integer before use."],"tags":["interactions","pointer-press","typecheck","ruby"],"backgroundTag":null,"analyzedSha":"aa36b38e696a0909e973bdf5e2f9031ffe842c4b","analyzedAt":"2026-08-14T02:32:32.244Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}