SeleniumHQ/selenium · error · ArgumentError

preference values must be plain strings: #{key.inspect} => #

Error message

preference values must be plain strings: #{key.inspect} => #{value.inspect}

What it means

Raised by Firefox::Profile#[]= (ArgumentError) when the value is a String but Util.stringified?(value) is true — i.e. the string already looks like a stringified literal (it appears quoted/encoded). Firefox preferences must be plain unquoted strings; a value like "'true'" or '\"100\"' would be double-encoded when serialized to prefs.js.

Source

Thrown at rb/lib/selenium/webdriver/firefox/profile.rb:105

          update_user_prefs_in(profile_dir)

          profile_dir
        end

        #
        # Set a preference for this particular profile.
        #
        # @see http://kb.mozillazine.org/About:config_entries
        # @see http://preferential.mozdev.org/preferences.html
        #

        def []=(key, value)
          unless VALID_PREFERENCE_TYPES.any? { |e| value.is_a? e }
            raise TypeError, "expected one of #{VALID_PREFERENCE_TYPES.inspect}, got #{value.inspect}:#{value.class}"
          end

          if value.is_a?(String) && Util.stringified?(value)
            raise ArgumentError, "preference values must be plain strings: #{key.inspect} => #{value.inspect}"
          end

          @additional_prefs[key.to_s] = value
        end

        def port=(port)
          WebDriver.logger.deprecate('Firefox::Profile#port=', 'the Service class', id: :firefox_profile)
          self[WEBDRIVER_PREFS[:port]] = port
        end

        def secure_ssl=(value)
          WebDriver.logger.deprecate('Firefox::Profile#secure_ssl=', id: :firefox_profile)
          @secure_ssl = value
        end

        def load_no_focus_lib=(value)
          WebDriver.logger.deprecate('Firefox::Profile#load_no_focus_lib=', id: :firefox_profile)
          @load_no_focus_lib = value

View on GitHub (pinned to aa36b38e69)

Solutions

  1. Pass the raw unquoted string (e.g. 'true' not '"true"').
  2. If the value genuinely needs to be a non-string type, pass the actual boolean/number instead of its string form.
  3. Strip accidental surrounding quotes before assigning.

Example fix

// before
profile['my.pref'] = '"enabled"'  # extra quotes -> ArgumentError

// after
profile['my.pref'] = 'enabled'  # plain string
Defensive patterns

Strategy: validation

Validate before calling

value = value.to_s
value = value.gsub(/\A['"]+|['"]+\z/, '') if Selenium::WebDriver::Util.stringified?(value)
profile[key] = value

Type guard

def plain_string?(value)
  value.is_a?(String) && !Selenium::WebDriver::Util.stringified?(value)
end

Prevention

When it happens

Trigger: Passing a string that begins/ends with quotes (e.g. '"true"', "'100'") or otherwise looks pre-stringified to profile[]=.

Common situations: Values read from JSON/YAML that retained surrounding quotes; copy-pasting example values that include quote characters; building preference strings via interpolation that adds quotes.

Related errors


AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14). Data as JSON: /api/errors/9ab0a521d08d24b1. Report an issue: GitHub.