New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 820080 link

Starred by 15 users

Issue metadata

Status: Assigned
Owner:
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux , Windows , Mac
Pri: 1
Type: Bug-Regression



Sign in to add a comment

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 description

UserAgent: 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:
 
Components: UI
Labels: Needs-Bisect Needs-Triage-M64
Cc: sindhu.chelamcherla@chromium.org
Components: Platform>Extensions
Labels: Triaged-ET Needs-Feedback
@Reporter: Please provide sample test file/extension to test this issue from TE end. This would help in further triaging of the issue.

Thanks!
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
tabClosed.js
707 bytes View Download
Project Member

Comment 4 by sheriffbot@chromium.org, Mar 9 2018

Labels: -Needs-Feedback
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
Labels: Needs-Feedback
@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!
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.
chrome-test-ext-0.0.1.zip
1.6 KB Download
getting_inbound_call.gif
1.2 MB View Download
Also attached are system/chrome specs from gif above.
Screen Shot 2018-03-12 at 12.49.38 PM.png
70.9 KB View Download
Screen Shot 2018-03-12 at 12.51.27 PM.png
204 KB View Download
Project Member

Comment 8 by sheriffbot@chromium.org, Mar 12 2018

Labels: -Needs-Feedback
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

Comment 9 by woxxom@gmail.com, 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.
test-ext.zip
675 bytes Download

Comment 10 by timdorr@gmail.com, Mar 12 2018

I can confirm this behavior on macOS 10.13.3 with Chrome 65.0.3325.146.
I am also seeing this behavior on Windows 10 and macOS 10.12.6, both with Chrome 65.0.3325.146.
Labels: -Pri-2 -Needs-Bisect hasbisect-per-revision Target-67 Target-66 M-67 FoundIn-66 FoundIn-67 Target-65 FoundIn-65 ReleaseBlock-Stable OS-Linux OS-Windows Pri-1
Owner: nasko@chromium.org
Status: Assigned (was: Unconfirmed)
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!
Labels: RegressedIn-64

Comment 14 by nasko@chromium.org, Mar 19 2018

Cc: rdevlin....@chromium.org nasko@chromium.org
Owner: rdevlin....@chromium.org
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?

Owner: karandeepb@chromium.org
Karan, can you take a look at this?
Will be able to take a look tomorrow.
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?

Comment 18 by woxxom@gmail.com, 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.
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.

Comment 20 by woxxom@gmail.com, 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.

Comment 21 by woxxom@gmail.com, 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.
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. 

Comment 23 by woxxom@gmail.com, 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?
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.
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.
>> 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).
Labels: -ReleaseBlock-Stable
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. "

Labels: Hotlist-DesktopUIValid Hotlist-DesktopUIChecked
*** Mass UI Triage ***

Able to reproduce the issue on Chrome #72.0.3617.0

Sign in to add a comment