Skip to content

Conversation

@asolntsev
Copy link
Contributor

@asolntsev asolntsev commented Jan 16, 2026

@diemol @titusfortner We need to get this fix to 4.40.0 release.

User description

In BiDi spec, its type is "TEXT".

Latest FireFox 147.0 returns UUID in field "internalId":

{
  "type" : "node",
  "sharedId" : "5dd958fd-0033-4b3a-b06a-f9eec9db2c85",
  "value" : { ... },
  "internalId" : "df8e0744-b1db-49b2-96df-45bd0d70dcd3"
}

Stack trace:

Exception in thread "BiDi Connection" org.openqa.selenium.bidi.BiDiException: Unable to process: {"type":"event","method":"log.entryAdded","params":{"type":"console","method":"log","source":{"realm":"9df00687-aa19-411c-a53f-bdb338b7abd8","context":"c6cc0a2e-8ba7-4c54-b58a-3615367747d7"},"args":[{"type":"object","value":[["originalEvent",{"type":"object"}],["type",{"type":"string","value":"keyup"}],["isDefaultPrevented",{"type":"function"}],["timeStamp",{"type":"number","value":339}],["jQuery183020487445442839158",{"type":"boolean","value":true}],["keyCode",{"type":"number","value":67}],["key",{"type":"string","value":"c"}],["charCode",{"type":"number","value":0}],["char",{"type":"undefined"}],["which",{"type":"number","value":67}],["view",{"type":"window","value":{"context":"10","isTopBrowsingContext":true}}],["target",{"type":"node","sharedId":"e5d288b2-6404-455b-aac1-9150c047bd08","value":{"nodeType":1,"localName":"input","namespaceURI":"http://www.w3.org/1999/xhtml","childNodeCount":0,"attributes":{"id":"tags","class":"ui-autocomplete-input","autocomplete":"off"},"shadowRoot":null},"internalId":"a7f2ac11-981a-4b84-ac22-7cb6d3c152ab"}],["shiftKey",{"type":"boolean","value":false}],["relatedTarget",{"type":"undefined"}],["metaKey",{"type":"boolean","value":false}],["eventPhase",{"type":"number","value":2}],["currentTarget",{"type":"node","sharedId":"e5d288b2-6404-455b-aac1-9150c047bd08","internalId":"a7f2ac11-981a-4b84-ac22-7cb6d3c152ab","value":{"nodeType":1,"localName":"input","namespaceURI":"http://www.w3.org/1999/xhtml","childNodeCount":0,"attributes":{"id":"tags","class":"ui-autocomplete-input","autocomplete":"off"},"shadowRoot":null}}],["ctrlKey",{"type":"boolean","value":false}],["cancelable",{"type":"boolean","value":true}],["bubbles",{"type":"boolean","value":true}],["altKey",{"type":"boolean","value":false}],["srcElement",{"type":"node","sharedId":"e5d288b2-6404-455b-aac1-9150c047bd08","internalId":"a7f2ac11-981a-4b84-ac22-7cb6d3c152ab","value":{"nodeType":1,"localName":"input","namespaceURI":"http://www.w3.org/1999/xhtml","childNodeCount":0,"attributes":{"id":"tags","class":"ui-autocomplete-input","autocomplete":"off"},"shadowRoot":null}}],["relatedNode",{"type":"undefined"}],["attrName",{"type":"undefined"}],["attrChange",{"type":"undefined"}],["delegateTarget",{"type":"node","sharedId":"e5d288b2-6404-455b-aac1-9150c047bd08","internalId":"a7f2ac11-981a-4b84-ac22-7cb6d3c152ab","value":{"nodeType":1,"localName":"input","namespaceURI":"http://www.w3.org/1999/xhtml","childNodeCount":0,"attributes":{"id":"tags","class":"ui-autocomplete-input","autocomplete":"off"},"shadowRoot":null}}],["data",{"type":"undefined"}],["handleObj",{"type":"object","value":[["type",{"type":"string","value":"keyup"}],["origType",{"type":"string","value":"keyup"}],["data",{"type":"undefined"}],["handler",{"type":"function"}],["guid",{"type":"number","value":7}],["selector",{"type":"undefined"}],["needsContext",{"type":"undefined"}],["namespace",{"type":"string","value":""}]]}]]}],"level":"info","text":"[object Object]","timestamp":1768573719871}}
	at org.openqa.selenium.bidi.Connection$Listener.lambda$onText$0(Connection.java:279)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at java.base/java.lang.Thread.run(Thread.java:840)
Caused by: org.openqa.selenium.json.JsonException: Unable to create instance of class org.openqa.selenium.bidi.log.ConsoleLogEntry
Build info: version: '4.40.0-SNAPSHOT', revision: '048a50178d*'
System info: os.name: 'Mac OS X', os.arch: 'aarch64', os.version: '26.2', java.version: '17.0.17'
Driver info: driver.version: unknown
	at org.openqa.selenium.json.StaticInitializerCoercer.lambda$apply$0(StaticInitializerCoercer.java:61)
	at org.openqa.selenium.json.JsonTypeCoercer.lambda$buildCoercer$6(JsonTypeCoercer.java:171)
	at org.openqa.selenium.json.JsonTypeCoercer.coerce(JsonTypeCoercer.java:146)
	at org.openqa.selenium.json.JsonInput.read(JsonInput.java:428)
	at org.openqa.selenium.bidi.log.Log.lambda$entryAdded$0(Log.java:49)
	at org.openqa.selenium.bidi.Connection.lambda$handleEventResponse$7(Connection.java:372)
	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
	at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
	at java.base/java.util.HashMap$EntrySpliterator.forEachRemaining(HashMap.java:1850)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
	at org.openqa.selenium.bidi.Connection.handleEventResponse(Connection.java:367)
	at org.openqa.selenium.bidi.Connection.handle(Connection.java:304)
	at org.openqa.selenium.bidi.Connection$Listener.lambda$onText$0(Connection.java:277)
	... 3 more
Caused by: java.lang.reflect.InvocationTargetException
	at jdk.internal.reflect.GeneratedMethodAccessor3.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
	at org.openqa.selenium.json.StaticInitializerCoercer.lambda$apply$0(StaticInitializerCoercer.java:59)
	... 20 more
Caused by: org.openqa.selenium.json.JsonException: Unable to create instance of class org.openqa.selenium.bidi.script.RemoteValue
Build info: version: '4.40.0-SNAPSHOT', revision: '048a50178d*'
System info: os.name: 'Mac OS X', os.arch: 'aarch64', os.version: '26.2', java.version: '17.0.17'
Driver info: driver.version: unknown
	at org.openqa.selenium.json.StaticInitializerCoercer.lambda$apply$0(StaticInitializerCoercer.java:61)
	at org.openqa.selenium.json.JsonTypeCoercer.lambda$buildCoercer$6(JsonTypeCoercer.java:171)
	at org.openqa.selenium.json.JsonTypeCoercer.coerce(JsonTypeCoercer.java:146)
	at org.openqa.selenium.json.CollectionCoercer.lambda$apply$0(CollectionCoercer.java:63)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
	at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1845)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
	at org.openqa.selenium.json.CollectionCoercer.lambda$apply$1(CollectionCoercer.java:64)
	at org.openqa.selenium.json.JsonTypeCoercer.lambda$buildCoercer$6(JsonTypeCoercer.java:171)
	at org.openqa.selenium.json.JsonTypeCoercer.coerce(JsonTypeCoercer.java:146)
	at org.openqa.selenium.json.JsonInput.read(JsonInput.java:428)
	at org.openqa.selenium.bidi.log.ConsoleLogEntry.fromJson(ConsoleLogEntry.java:98)
	... 24 more
Caused by: java.lang.reflect.InvocationTargetException
	at jdk.internal.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
	at org.openqa.selenium.json.StaticInitializerCoercer.lambda$apply$0(StaticInitializerCoercer.java:59)
	... 40 more
Caused by: org.openqa.selenium.json.JsonException: Unable to create instance of class org.openqa.selenium.bidi.script.RemoteValue
Build info: version: '4.40.0-SNAPSHOT', revision: '048a50178d*'
System info: os.name: 'Mac OS X', os.arch: 'aarch64', os.version: '26.2', java.version: '17.0.17'
Driver info: driver.version: unknown
	at org.openqa.selenium.json.StaticInitializerCoercer.lambda$apply$0(StaticInitializerCoercer.java:61)
	at org.openqa.selenium.json.JsonTypeCoercer.lambda$buildCoercer$6(JsonTypeCoercer.java:171)
	at org.openqa.selenium.json.JsonTypeCoercer.coerce(JsonTypeCoercer.java:146)
	at org.openqa.selenium.json.JsonInput.read(JsonInput.java:428)
	at org.openqa.selenium.bidi.script.RemoteValue.deserializeValue(RemoteValue.java:223)
	at org.openqa.selenium.bidi.script.RemoteValue.fromJson(RemoteValue.java:157)
	... 44 more
Caused by: java.lang.reflect.InvocationTargetException
	at jdk.internal.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
	at org.openqa.selenium.json.StaticInitializerCoercer.lambda$apply$0(StaticInitializerCoercer.java:59)
	... 49 more
Caused by: org.openqa.selenium.json.JsonException: java.lang.NumberFormatException: Character array is missing "e" notation exponential mark.
Build info: version: '4.40.0-SNAPSHOT', revision: '048a50178d*'
System info: os.name: 'Mac OS X', os.arch: 'aarch64', os.version: '26.2', java.version: '17.0.17'
Driver info: driver.version: unknown
	at org.openqa.selenium.json.NumberCoercer.lambda$apply$0(NumberCoercer.java:68)
	at org.openqa.selenium.json.JsonTypeCoercer.lambda$buildCoercer$6(JsonTypeCoercer.java:171)
	at org.openqa.selenium.json.JsonTypeCoercer.coerce(JsonTypeCoercer.java:146)
	at org.openqa.selenium.json.JsonInput.read(JsonInput.java:428)
	at org.openqa.selenium.bidi.script.RemoteValue.fromJson(RemoteValue.java:136)
	... 53 more
Caused by: java.lang.NumberFormatException: Character array is missing "e" notation exponential mark.
	at java.base/java.math.BigDecimal.<init>(BigDecimal.java:645)
	at java.base/java.math.BigDecimal.<init>(BigDecimal.java:471)
	at java.base/java.math.BigDecimal.<init>(BigDecimal.java:900)
	at org.openqa.selenium.json.NumberCoercer.lambda$apply$0(NumberCoercer.java:66)
	... 57 more

🔄 Types of changes

  • Bug fix (backwards compatible)

PR Type

Bug fix


Description

  • Change BiDi internalId field type from Long to String

  • Align with BiDi specification where type is TEXT

  • Support Firefox 147.0+ UUID format for internalId


Diagram Walkthrough

flowchart LR
  A["RemoteValue class"] -- "internalId field type change" --> B["Long to String"]
  B -- "affects" --> C["Constructor parameter"]
  B -- "affects" --> D["fromJson deserialization"]
  B -- "affects" --> E["getInternalId getter"]
Loading

File Walkthrough

Relevant files
Bug fix
RemoteValue.java
Update internalId field type to String                                     

java/src/org/openqa/selenium/bidi/script/RemoteValue.java

  • Changed internalId field type from Optional to Optional
  • Updated constructor parameter type for internalId
  • Modified fromJson() method to deserialize internalId as String instead
    of Long
  • Updated getInternalId() getter return type to Optional
+5/-5     

In BiDi spec, its type is "TEXT".

Latest FireFox 147.0 returns UUID in field "internalId":

{
  "type" : "node",
  "sharedId" : "5dd958fd-0033-4b3a-b06a-f9eec9db2c85",
  "value" : { ... },
  "internalId" : "df8e0744-b1db-49b2-96df-45bd0d70dcd3"
}
@selenium-ci selenium-ci added C-java Java Bindings B-devtools Includes everything BiDi or Chrome DevTools related labels Jan 16, 2026
@qodo-code-review
Copy link
Contributor

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🟢
No security concerns identified No security vulnerabilities detected by AI analysis. Human verification advised for critical code.
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
Backward compat parsing: fromJson() now reads internalId strictly as String, which may fail or yield unexpected
behavior if upstream sources still send numeric IDs (previously Long) unless the JSON
parser layer transparently converts numbers-to-strings.

Referred Code
public static RemoteValue fromJson(JsonInput input) {
  Type type = null;

  Optional<String> handle = Optional.empty();

  Optional<String> internalId = Optional.empty();

  Optional<Object> value = Optional.empty();

  Optional<String> sharedId = Optional.empty();

  input.beginObject();
  while (input.hasNext()) {
    switch (input.nextName()) {
      case "type":
        String typeString = input.read(String.class);
        type = Type.findByName(typeString);
        break;

      case "handle":
        handle = Optional.ofNullable(input.read(String.class));


 ... (clipped 5 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@asolntsev asolntsev added this to the 4.40.0 milestone Jan 16, 2026
@asolntsev asolntsev self-assigned this Jan 16, 2026
@asolntsev asolntsev added D-firefox P-bug fix PR addresses a known issue labels Jan 16, 2026
@qodo-code-review
Copy link
Contributor

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Support numeric or string internalId

In the fromJson method, read internalId as an Object and convert it to a String
to handle cases where it might be sent as a number instead of a string.

java/src/org/openqa/selenium/bidi/script/RemoteValue.java [135-137]

 case "internalId":
-  internalId = Optional.ofNullable(input.read(String.class));
+  Object idValue = input.read(Object.class);
+  internalId = Optional.ofNullable(idValue).map(Object::toString);
   break;
  • Apply / Chat
Suggestion importance[1-10]: 6

__

Why: This suggestion improves robustness by gracefully handling a numeric internalId and converting it to a string, which is plausible given the PR's change from Long to String and could prevent a JsonException.

Low
Learned
best practice
Validate and normalize string input

Treat internalId as an integration-boundary value: trim it and convert
blank/whitespace-only strings to Optional.empty() so callers don't have to
handle meaningless IDs.

java/src/org/openqa/selenium/bidi/script/RemoteValue.java [135-137]

 case "internalId":
-  internalId = Optional.ofNullable(input.read(String.class));
+  String rawInternalId = input.read(String.class);
+  if (rawInternalId != null) {
+    rawInternalId = rawInternalId.trim();
+  }
+  internalId = (rawInternalId == null || rawInternalId.isEmpty())
+      ? Optional.empty()
+      : Optional.of(rawInternalId);
   break;
  • Apply / Chat
Suggestion importance[1-10]: 6

__

Why:
Relevant best practice - Add explicit validation/guards at integration boundaries by trimming inputs and checking presence before use.

Low
General
Add constructor null checks

Add Objects.requireNonNull checks for all parameters in the RemoteValue
constructor to prevent NullPointerException.

java/src/org/openqa/selenium/bidi/script/RemoteValue.java [99-110]

 public RemoteValue(
     Type type,
     Optional<String> handle,
     Optional<String> internalId,
     Optional<Object> value,
     Optional<String> sharedId) {
-  this.type = type;
-  this.handle = handle;
-  this.internalId = internalId;
-  this.value = value;
-  this.sharedId = sharedId;
+  this.type = Objects.requireNonNull(type, "type");
+  this.handle = Objects.requireNonNull(handle, "handle");
+  this.internalId = Objects.requireNonNull(internalId, "internalId");
+  this.value = Objects.requireNonNull(value, "value");
+  this.sharedId = Objects.requireNonNull(sharedId, "sharedId");
 }
  • Apply / Chat
Suggestion importance[1-10]: 4

__

Why: The suggestion adds null-safety checks to the constructor, which is good practice, but the only internal caller (fromJson) already ensures non-null Optional instances are passed, making this a low-impact defensive change.

Low
  • More

@cgoldberg cgoldberg changed the title change BiDi "internalId" type from Long to String [java] Change BiDi "internalId" type from Long to String Jan 16, 2026
@asolntsev asolntsev merged commit 48e94cf into SeleniumHQ:trunk Jan 16, 2026
16 of 17 checks passed
@asolntsev asolntsev deleted the fix/bidi/internal-id-type branch January 16, 2026 20:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

B-devtools Includes everything BiDi or Chrome DevTools related C-java Java Bindings D-firefox P-bug fix PR addresses a known issue Review effort 1/5

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants