Skip to content

Regression after update to nodriver 44 #2175

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Lyesbcb opened this issue Apr 7, 2025 · 5 comments
Open

Regression after update to nodriver 44 #2175

Lyesbcb opened this issue Apr 7, 2025 · 5 comments

Comments

@Lyesbcb
Copy link

Lyesbcb commented Apr 7, 2025

Description

Hi team,

After updating Chrome to version 135.0.7049.42 (Official Build) (arm64) on macOS, I'm encountering issues with evaluate() using nodriver. Everything was working correctly before this update. Here's what's happening now:


Machine 1 (Mac M1):

Using the following code:

exist = await tab.evaluate(read_asset("tasks/utils/verifyIsDisplayById.js", "browser", {"ID": id}))
print(exist)

With the JS being injected:

document.getElementById('{ID}') !== null;

Before Chrome 135, the result was a simple boolean (True or False). Now it returns:

(RemoteObject(type_='boolean', value=False, ...), None)

This change broke existing logic since .value must now be manually extracted, which wasn’t necessary before.


Machine 2 (also macOS):

The exact same code now fails with:

'NoneType' object has no attribute 'evaluate'

This suggests that tab is unexpectedly None. Again, this worked flawlessly before the Chrome 135 update.


Summary:

  • Regression after Chrome 135 (arm64 build on macOS).
  • evaluate() behavior has changed: returns RemoteObject, breaking previous simple True/False handling.
  • On a second machine, tab is None, possibly due to session/connection issues.
  • Everything worked fine before updating Chrome.

Any idea what changed with the new version, or how to restore the previous behavior?

Thanks in advance!

Update 1

The error doesn't come from Chrome Version but from nodriver version in 41 it's working but in 44 it's not working.

Update 2

In the last update the return_by_value parameter in tab.evaluate is False by default (in the documentation it's say it's True).

I had return_by_value=True in the parameter and it's works

Others breaking change ?

In my code I access to some data with

data = await tab.evaluate("window.ordersListData", return_by_value=True)

In nodriver 41 it's working but in nodriver 44 it's return None always

Update 3

i find the breaking change. When I remove this code in blue in the nodriver 44 version my evaluate working fine. I don't realy understand why.

Image

It's from this commit

@Lyesbcb Lyesbcb changed the title Regression after Chrome 135 update: evaluate returns unexpected RemoteObject or fails with 'NoneType' object has no attribute 'evaluate' Regression after Chrome nodriver 44 Apr 7, 2025
@Lyesbcb Lyesbcb changed the title Regression after Chrome nodriver 44 Regression after update to nodriver 44 Apr 7, 2025
@ultrafunkamsterdam
Copy link
Owner

I have an update already for evaluate I'm sorry haven't pushed it yet

@Lyesbcb
Copy link
Author

Lyesbcb commented Apr 21, 2025

Hey @ultrafunkamsterdam, I'm facing almost the same issue, but I'm still on version 0.44.

The only difference is that I'm running on Windows 11 instead of Mac OS.

On Mac OS :

data = await tab.evaluate("window.listItemsData", return_by_value=True)
print(data) # [all my data]

remoteObject = await tab.evaluate("window.listItemsData", return_by_value=False)
print(remoteObject) # RemoteObject (RemoteObject(type_='object', subtype='array', class_name='Array', value=None, unserializable_value=None, description='Array(75)', deep_serialized_value=None, object_id=RemoteObjectId('5630152491970979954.3.1'), preview=None, custom_preview=None), None)

On Windows :

In my my remote object, I retrieved the data correctly, but if I set "return_by_value=True," I only get None.

data = await tab.evaluate("window.listItemsData", return_by_value=True)
print(data) # None

remoteObject = await tab.evaluate("window.listItemsData", return_by_value=False)
print(remoteObject) # RemoteObject (RemoteObject(type_='object', subtype='array', class_name='Array', value=[all my data], unserializable_value=[all my data], description='Array(75)', deep_serialized_value=None, object_id=RemoteObjectId('5630152491970979954.3.1'), preview=[all my data], custom_preview=[all my data]), None)

Do you have any idea where this might be coming from?

Thank you!

@ultrafunkamsterdam
Copy link
Owner

Hey @ultrafunkamsterdam, I'm facing almost the same issue, but I'm still on version 0.44.

The only difference is that I'm running on Windows 11 instead of Mac OS.

On Mac OS :

data = await tab.evaluate("window.listItemsData", return_by_value=True)
print(data) # [all my data]

remoteObject = await tab.evaluate("window.listItemsData", return_by_value=False)
print(remoteObject) # RemoteObject (RemoteObject(type_='object', subtype='array', class_name='Array', value=None, unserializable_value=None, description='Array(75)', deep_serialized_value=None, object_id=RemoteObjectId('5630152491970979954.3.1'), preview=None, custom_preview=None), None)

On Windows :

In my my remote object, I retrieved the data correctly, but if I set "return_by_value=True," I only get None.

data = await tab.evaluate("window.listItemsData", return_by_value=True)
print(data) # None

remoteObject = await tab.evaluate("window.listItemsData", return_by_value=False)
print(remoteObject) # RemoteObject (RemoteObject(type_='object', subtype='array', class_name='Array', value=[all my data], unserializable_value=[all my data], description='Array(75)', deep_serialized_value=None, object_id=RemoteObjectId('5630152491970979954.3.1'), preview=[all my data], custom_preview=[all my data]), None)
Do you have any idea where this might be coming from?

Thank you!

Dont use return by value.

@nathanfallet
Copy link

nathanfallet commented Apr 22, 2025

@ultrafunkamsterdam We made something like this for now, any recommendations?

async def tab_evaluate(tab: Tab, js: str):
    data = await tab.evaluate(js, return_by_value=False)
    if isinstance(data, tuple):
        remote_object, _ = data
        return convert_deep_serialized_value(
            remote_object.deep_serialized_value.type_,
            remote_object.deep_serialized_value.value
        )
    if data is None:
        return None
    type_ = ""
    if isinstance(data, list):
        type_ = "array"
    elif isinstance(data, dict):
        type_ = "object"
    return convert_deep_serialized_value(type_, data)


def convert_deep_serialized_value(type_: str, value):
    if type_ == "array":
        return [
            convert_deep_serialized_value(v["type"], v["value"] if "value" in v else None)
            for v in value
        ]
    if type_ == "object":
        return {
            v[0]: convert_deep_serialized_value(v[1]["type"], v[1]["value"] if "value" in v[1] else None)
            for v in value
        }

    # Other, eg. string, number, ...
    return value

EDIT: Because sometimes there are things working on macOS but not on Windows (.value is always None on Windows for example), so we have to

@ultrafunkamsterdam
Copy link
Owner

@ultrafunkamsterdam We made something like this for now, any recommendations?

async def tab_evaluate(tab: Tab, js: str):
data = await tab.evaluate(js, return_by_value=False)
if isinstance(data, tuple):
remote_object, _ = data
return convert_deep_serialized_value(
remote_object.deep_serialized_value.type_,
remote_object.deep_serialized_value.value
)
if data is None:
return None
type_ = ""
if isinstance(data, list):
type_ = "array"
elif isinstance(data, dict):
type_ = "object"
return convert_deep_serialized_value(type_, data)

def convert_deep_serialized_value(type_: str, value):
if type_ == "array":
return [
convert_deep_serialized_value(v["type"], v["value"] if "value" in v else None)
for v in value
]
if type_ == "object":
return {
v[0]: convert_deep_serialized_value(v[1]["type"], v[1]["value"] if "value" in v[1] else None)
for v in value
}

# Other, eg. string, number, ...
return value

EDIT: Because sometimes there are things working on macOS but not on Windows (.value is always None on Windows for example), so we have to

Just use the original tab.evaluate. maybe you need to update nodriver first

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants
@ultrafunkamsterdam @nathanfallet @Lyesbcb and others