Getting an error tabs.executeScript: The tab was closed. when the tab is open and active from chrome extension
Reported by
drew.pfu...@salesloft.com,
Mar 8 2018
|
|||||||||||
Issue descriptionUserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36 Steps to reproduce the problem: 1. create tab via chrome.tabs.create 2. run chrome.tabs.executeScript on that new tab 3. chrome.runtime.lastError will be Unchecked runtime.lastError while running tabs.executeScript: The tab was closed. What is the expected behavior? the tab is open and active, so execute script should run. What went wrong? We create a tab and run chrome.tabs.executeScript with that new tab id, but are getting the following error: Unchecked runtime.lastError while running tabs.executeScript: The tab was closed. We are using the built in callbacks so it shouldn't be a race condition. This works fine on OSX 10.12.6 but seems to become an issue on OSX High Sierra and Chrome 64. Did this work before? Yes chrome 63 Does this work in other browsers? N/A Chrome version: 64.0.3282.186 Channel: stable OS Version: OS X 10.13 Flash Version:
,
Mar 9 2018
@Reporter: Please provide sample test file/extension to test this issue from TE end. This would help in further triaging of the issue. Thanks!
,
Mar 9 2018
If you run the attached js snippet in the background page console of an extension, chrome.runtime.lastError will be {message: “The tab was closed.“}
Note you will need to create an empty js file called widget.bundle.js
,
Mar 9 2018
Thank you for providing more feedback. Adding the requester to the cc list. For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
,
Mar 12 2018
@Reporter: Please provide sample extension file in zipped folder to test this issue. Also if possible please provide video on reproducing this issue. This would help in further debugging of issue. Thanks!
,
Mar 12 2018
Attached is a test extension. It will create a new tab and try to execute a script on it. It will log the error "The tab was closed" when it fails. It executes on load so reload the background page to reproduce. Also attached Gif of issue. Notice it says the new tab is closed, but the current active tab is the same new tab the script tries to execute on.
,
Mar 12 2018
Also attached are system/chrome specs from gif above.
,
Mar 12 2018
Thank you for providing more feedback. Adding the requester to the cc list. For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
,
Mar 12 2018
It happens because the http:// URL is redirected by the site to https:// and Chrome 64+ has a problem with this. Bisect info: 520602 (good) - 520617 (bad) https://chromium.googlesource.com/chromium/src/+log/58306c2d..d919f362?pretty=fuller Suspecting r520605 "Respect the process limit on same-site new tabs." Suspecting r520614 "Standardize ResourceClient data streaming callbacks on ResourceClient::DataReceived" Landed in 64.0.3282.0 A per-revision bisect would be helpful. I'm attaching a simplified test extension that displays "GOOD" or "BAD" for good/build builds respectively.
,
Mar 12 2018
I can confirm this behavior on macOS 10.13.3 with Chrome 65.0.3325.146.
,
Mar 12 2018
I am also seeing this behavior on Windows 10 and macOS 10.12.6, both with Chrome 65.0.3325.146.
,
Mar 13 2018
Able to reproduce this issue on reported version 64.0.3282.168, on latest stable 65.0.3325.146 and on latest canary 67.0.3368.0 using Mac 10.13.3, Windows 10 and Ubuntu 14.04 with extensions provided in comment#6 and #9. Hence bisected with extension given in comment#9. Good Build: 64.0.3281.0 Bad Build: 64.0.3282.0 You are probably looking for a change made after 520604 (known good), but no later than 520605 (first known bad). CHANGELOG URL: https://chromium.googlesource.com/chromium/src/+log/809e79dc1dd5949bfca5cc93287244664d60ee2c..deb6c7eade28984a7952134532e28998dca1c8f0 Reviewed-on: https://chromium-review.googlesource.com/794952 Suspecting same from changelog. @nasko: Please confirm whether this is a bug or intended behavior. As Issue is reproducible on M-64 also not adding RB-Stable for M-65. Adding RB-Stable for M-67. Please remove if not the case. Thanks!
,
Mar 13 2018
,
Mar 19 2018
The CL that is blamed doesn't really change how tabs are created, just ensures that the proper SiteInstance is used when we create one. rdevlin.cronin@, can someone from the extensions team take a look what causes this to occur?
,
Mar 19 2018
Karan, can you take a look at this?
,
Mar 19 2018
Will be able to take a look tomorrow.
,
Apr 3 2018
So I gave this an initial look testing with the case in c#9 and here is what I think is happening:
When we invoke, chrome.tabs.create({url: "some url"}, function(tab) {}), the browser process just creates a new tab/WebContents and starts a navigation to the specified |url| and returns the result to the extension. Note: The browser doesn't wait for the initial navigation to complete before dispatching the response to the extension. (tab.url would correspond to the visible url and not the last committed url in the WebContents).
Now in the extension's callback, the extension can choose to inject a script into the newly created tab using chrome.tabs.executeScript. When the browser receives this request from the extension, it may happen (it does in the given example) that the newly created WebContents/tab is still undergoing navigation in its main frame. The browser process will then inject the script into the frame returned by WebContents::GetMainFrame(). If somehow the navigation causes this frame to be swapped out, the script injection fails.
Before r520605 for the given test case, we were not specifying a site instance for the WebContents created through chrome.tabs.create (tab_util::GetSiteInstanceForNewTab return nullptr). As a result the newly created main RFH had a "site-less" SiteInstance (created using SiteInstance::Create(browser_context)) and the main frame navigation did not involve a swapping of the RFH (even if the navigation request redirected from http://www.google.com/ to https://www.google.com/). Hence the script injection into the frame returned by WebContents::GetMainFrame worked.
After r520605, we created a site instance (bound to http://google.com in the given example) for the newly created main RFH in chrome.tabs.create. The navigation request was then redirected to https://www.google.com. Hence the navigation was committed in a different RFH. But the script injected through WebContents::GetMainFrame was injected into the old RFH (this should be racy). Since the old host was subequently swapped out when the navigation committed, script injection failed.
In a way this is WAI. chrome.tabs.create doesn't promise to return after the navigation completes and chrome.tabs.executeScript may fail if the passed tab is undergoing a main frame navigation. Extension code can use chrome.tabs.onUpdated or the web navigation API to inject the script at the right time.
However, since this used to work before, we can update chrome.tabs.create (and similar functions) to only return once the navigation has committed. Thoughts?
,
Apr 3 2018
If the extensions need to wait for the URL to commit, I'm afraid that using executeScript to run at exactly document_start will be impossible or too unreliable to be practically usable.
,
Apr 3 2018
I am not sure if that has been reliable up till now. For e.g. I can see crbug.com/471801 and crbug.com/737007.
,
Apr 3 2018
* bug 471801 is about chrome.tabs.update being unreliable - which is exactly my point - but it's not relevant here as we're using chrome.tabs.create * bug 737007 is about passing data synchronously so it's not relevant here as well To reiterate, my concern is that previously chrome.tabs.create + chrome.tabs.executeScript with runAt:'document_start' would [more] reliably run the script before page scripts.
,
Apr 3 2018
[er, finishing the sentence] ... but if you make chrome.tabs.create postpone the callback to the navigation being committed, it might reduce or obliterate the previously possible reliability.
,
Apr 3 2018
What I meant was that I think "chrome.tabs.create + chrome.tabs.executeScript with runAt:'document_start'" is also unreliable (at least from a design standpoint, from even before r520605). And you are correct that waiting for commit would make it even more unreliable.
,
Apr 3 2018
What do you think about frankensteining executeScript into chrome.tabs.create?
Like chrome.tabs.create({url: '...', executeScript: { .... }}, callback)
Looks terrible, I guess, but are there any alternatives?
,
Apr 3 2018
Actually it seems to me that 'document_start' case is already broken and there should be a different API solution to it. However let's also see what others have to say.
,
Apr 3 2018
If the callback to chrome.tabs.create is postponed until ReadyToCommitNavigation, it should be possible to execute script in the right RFH without waiting for the commit to happen. However, it might still have some side effects, since the document wouldn't have been created at that time. If it is possible to capture the script to execute at that time and pass it to the renderer, it can wait for DidCommitNavigation in the renderer itself and execute at that time (or the usual DidCreateDocumentElement?). Just some random thoughts, not sure if they are feasible.
,
Apr 3 2018
>> If the callback to chrome.tabs.create is postponed until ReadyToCommitNavigation, it should be possible to execute script in the right RFH without waiting for the commit to happen. However, it might still have some side effects, since the document wouldn't have been created at that time. Yeah that might work better. Not sure what side effects there could be, considering currently we dispatch the callback (possibly) even before RTCN. >> If it is possible to capture the script to execute at that time and pass it to the renderer, it can wait for DidCommitNavigation in the renderer itself and execute at that time (or the usual DidCreateDocumentElement?) The thing is when we are handling executeScript in the browser, we don't really have the context to know what is the right thing to do. (For e.g. whether we should wait for the next navigation to inject the script).
,
Apr 17 2018
I don't think this should be a Release-Block stable since as I posted earlier- "In a way this is WAI. chrome.tabs.create doesn't promise to return after the navigation completes and chrome.tabs.executeScript may fail if the passed tab is undergoing a main frame navigation. Extension code can use chrome.tabs.onUpdated or the web navigation API to inject the script at the right time. "
,
Nov 22
*** Mass UI Triage *** Able to reproduce the issue on Chrome #72.0.3617.0 |
|||||||||||
►
Sign in to add a comment |
|||||||||||
Comment 1 by susan.boorgula@chromium.org
, Mar 9 2018Labels: Needs-Bisect Needs-Triage-M64