SeleniumHQ/selenium · error · Error::SerializationError
#{name} received a variant not in this Selenium's BiDi schem
Error message
#{name} received a variant not in this Selenium's BiDi schema: #{json_payload.inspect} What it means
For a BiDi Union, select() picks a variant by inspecting the payload's discriminator keys. If no declared variant matches the keys present, the union cannot deserialize the response and raises Error::SerializationError noting the variant is not in this Selenium's BiDi schema. This is forward-compat friction: the browser sent something newer than this Selenium knows.
Source
Thrown at rb/lib/selenium/webdriver/bidi/serialization/union.rb:68
# Declared (via the schema's `scalarValues` signal) on a non-object_only union whose
# bare-scalar arms are a fixed set of literals (input.Origin's "viewport" / "pointer").
# An outbound scalar outside that set matches no arm, so it is a caller error.
def scalar_values(*values) = @scalar_values = values
# A non-Hash payload is a bare scalar arm (e.g. input.Origin's "viewport") with no
# object to dispatch on, so it is returned unchanged — unless every arm is an object
# (object_only), where a non-Hash cannot match any variant and is a wire error.
def from_json(json_payload)
unless json_payload.is_a?(::Hash)
return json_payload unless @object_only
raise Error::SerializationError, "#{name} expected an object on the wire, got #{json_payload.inspect}"
end
variant = select(json_payload)
unless variant
raise Error::SerializationError,
"#{name} received a variant not in this Selenium's BiDi schema: #{json_payload.inspect}"
end
Protocol.const_get(variant).from_json(json_payload)
end
# Outbound mirror of from_json: build the variant the command's kwargs describe
# so its typed as_json drives null-vs-absent per field (a flat hash through
# Transport cannot). Dispatch keys are wire names equal to their ruby kwarg
# (asserted at generation), so they match the kwargs by symbol. A mismatch here
# is a caller error (unlike an unknown inbound value), so it fails loudly.
def build(**kwargs)
variant = outbound_variant(kwargs) ||
raise(::ArgumentError, "no #{name} variant matches #{kwargs.inspect}")
klass = Protocol.const_get(variant)
# An omitted optional arrives as UNSET; forward only what was provided. A provided
# key that isn't a field of the chosen variant is an invalid combination for this union.
provided = kwargs.reject { |_, value| UNSET.equal?(value) }
invalid = provided.keys - klass.fields.map(&:name)View on GitHub (pinned to aa36b38e69)
Solutions
- Upgrade Selenium to a version whose schema includes the new variant.
- If you cannot upgrade, filter/avoid the BiDi event subscription that surfaces the unknown variant.
- Report the unknown variant payload so the schema can be extended.
- Downgrade the browser to match the Selenium schema if upgrading the client is blocked.
Defensive patterns
Strategy: validation
Validate before calling
# You cannot enumerate variants without the schema; the practical guard is version alignment. # Subscribe only to event types you know your Selenium supports. SUPPORTED_EVENTS = %w[log entryAdded browsingContext].freeze
Try / catch
begin
value = SomeUnion.from_json(payload)
rescue Selenium::WebDriver::Error::SerializationError => e
raise unless e.message =~ /variant not in this Selenium's BiDi schema/
warn "unknown BiDi variant (upgrade Selenium?): #{e.message}"
end Prevention
- Upgrade Selenium when adopting a newer browser that emits new BiDi variants.
- Subscribe only to BiDi events your Selenium schema knows about.
- Capture and report unknown-variant payloads upstream.
- Maintain a pinned, tested Selenium+browser version matrix.
When it happens
Trigger: Browser emits a BiDi object whose discriminator does not match any variant arm in the Selenium schema. Reached on any inbound union deserialization (e.g. log entry types, browsingContext event types).
Common situations: Browser newer than Selenium adding a new variant, Selenium schema out of date, grid forwarding unsupported event types, custom browser BiDi extension.
Related errors
- #{name} expected an object on the wire, got #{json_payload.i
- #{name} expected an object on the wire, got #{json_payload.i
- #{name}##{field.name} is required but was missing from the r
- #{name}##{field.name} received null but is not nullable
- #{name}##{field.name} expected #{field.list ? 'a list' : 'a
AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14).
Data as JSON: /api/errors/45fb08e1cbdc7fc4.
Report an issue: GitHub.