SeleniumHQ/selenium · error · Error::SerializationError

#{name}##{field.name} expected #{Array(field.scalar).join('

Error message

#{name}##{field.name} expected #{Array(field.scalar).join(' or ')}, got #{value.inspect}

What it means

scalar_value validates a bare scalar at a scalar-tolerant union position (e.g. input.Origin's 'viewport'/'pointer' literals). The scalar must match one of the union's scalar-arm primitives; a wrong-typed scalar (number where string expected) raises Error::SerializationError. An unrecognized primitive name is left unchecked (lenient default).

Source

Thrown at rb/lib/selenium/webdriver/bidi/serialization/record.rb:335

                raise Error::SerializationError,
                      "#{name}##{field.name} expected a [key, value] pair, got #{element.inspect}"
              end

              key, value = element
              key = key.is_a?(::Hash) ? klass.from_json(key) : scalar_value(field, key)
              [key, klass.from_json(value)]
            end

            # A bare scalar at a scalar-tolerant union position must match one of the union's
            # scalar-arm primitives (+scalar+ is a primitive name or an array of them); a
            # wrong-typed scalar (a number where a string is expected) is a wire error, not
            # something to pass through. An unrecognized primitive (none in PRIMITIVE_TYPES) is
            # left unchecked, matching the lenient default elsewhere.
            def scalar_value(field, value)
              expected = Array(field.scalar).flat_map { |primitive| PRIMITIVE_TYPES[primitive] || [] }
              return value if expected.empty? || expected.any? { |type| value.is_a?(type) }

              raise Error::SerializationError,
                    "#{name}##{field.name} expected #{Array(field.scalar).join(' or ')}, got #{value.inspect}"
            end

            def extra(json_payload)
              known = (@wire_keys ||= fields.map(&:wire_key))
              json_payload.except(*known)
            end

            # Forward-compat signal: a property a closed type does not model is dropped and warned so
            # schema drift is visible (an extensible type keeps its extras silently — the spec sanctions
            # them). Tagged +:bidi_undeclared_property+ so a caller can silence it via +logger.ignore+.
            def warn_undeclared(undeclared)
              undeclared.each_key do |key|
                WebDriver.logger.warn("#{name} received an undeclared property: #{key.inspect}",
                                      id: :bidi_undeclared_property)
              end
            end
          end

View on GitHub (pinned to aa36b38e69)

Solutions

  1. Pass one of the documented scalar literals for the union (e.g. :viewport / :pointer for input Origin).
  2. Check the field's scalar arms in the generated schema and use a matching value.
  3. Align Selenium and browser versions if the arms changed.

Example fix

// before
actions.move(origin: 123, x: 0, y: 0)
// after
actions.move(origin: :viewport, x: 0, y: 0)
Defensive patterns

Strategy: type-guard

Validate before calling

ALLOWED_ORIGINS = %w[viewport pointer].freeze

def valid_origin?(o)
  ALLOWED_ORIGINS.include?(o.to_s)
end

Type guard

def valid_union_scalar?(value, allowed)
  Array(allowed).include?(value.to_s) || Array(allowed).include?(value)
end

Try / catch

begin
  actions.move(origin: origin_value, x: 0, y: 0)
rescue Selenium::WebDriver::Error::SerializationError => e
  raise unless e.message =~ /expected .* or .*, got/
  warn "bad union scalar: #{e.message}"
end

Prevention

When it happens

Trigger: Inbound or outbound scalar at a union position whose type does not match any scalar arm — e.g. passing 123 to a union whose scalar arms are string literals, or 'x' where a number is expected.

Common situations: Caller passes the wrong literal/type to a BiDi input command (origin, button enums), schema/client skew on union scalar arms.

Related errors


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