Skip to content

ServiceWorker cannot be started #1180

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
mho22 opened this issue Apr 2, 2024 · 16 comments · Fixed by #1209
Open

ServiceWorker cannot be started #1180

mho22 opened this issue Apr 2, 2024 · 16 comments · Fixed by #1209
Labels
[Focus] Developer Tools [Type] Bug An existing feature does not function as intended

Comments

@mho22
Copy link
Contributor

mho22 commented Apr 2, 2024

When attempting to run npm run dev locally, I encountered this error:

TypeError: Failed to update a ServiceWorker for scope ('http://localhost:5400/') with script ('http://localhost:5400/service-worker.ts?type=module&worker_file'): ServiceWorker cannot be started
(anonymous) @ remote.html?html-proxy&index=0.js:9

It's evidently linked to a ServiceWorker update issue.

Upon examining the code, I discovered this line in packages/php-wasm/web/src/lib/register-service-worker.ts on line 47:

// Check if there's a new service worker available and, if so, enqueue
// the update:
await registration.update();

When I comment this line, everything works fine.

Here is a console.log of the registration object:

ServiceWorkerRegistration {installing: null, waiting: null, active: ServiceWorker, navigationPreload: NavigationPreloadManager, scope: 'http://localhost:5400/', …}
active :  ServiceWorker {scriptURL: 'http://localhost:5400/service-worker.ts?type=module&worker_file', state: 'activated', onstatechange: null, onerror: null}
backgroundFetch : BackgroundFetchManager {}
cookies : CookieStoreManager {}
installing : null
navigationPreload : NavigationPreloadManager {}
onupdatefound : null
paymentManager : PaymentManager {userHint: ''}
periodicSync : PeriodicSyncManager {}
pushManager : PushManager {}
scope : "http://localhost:5400/"
sync : SyncManager {}
updateViaCache : "none"
waiting :  null
[[Prototype]] : ServiceWorkerRegistration

I don't know if something is wrong or missing on my side, that's why I wrote this issue.

@adamziel adamziel added [Type] Bug An existing feature does not function as intended [Focus] Developer Tools labels Apr 2, 2024
@adamziel adamziel added this to the Meta – Contribution Tools milestone Apr 2, 2024
@adamziel
Copy link
Collaborator

adamziel commented Apr 2, 2024

@mho22 Would manually removing the service worker in devtools unblock you? I'm not sure why that problem happens either, perhaps @brandonpayton would have some insights. A quick solution could be to wrap it in try/catch (but only in the local development environment) and propagate the error to the logger.

@mho22
Copy link
Contributor Author

mho22 commented Apr 2, 2024

@adamziel Anytime the page refreshes, it returns the error. Even if I remove the service worker in devtools manually. I wrapped the line in a try/catch to show you the result :

try
{
	// Check if there's a new service worker available and, if so, enqueue
	// the update:
	await registration.update();
}
catch( error )
{
	console.debug( error );
} 
Capture d’écran 2024-04-02 à 15 07 16

@brandonpayton
Copy link
Member

Hi @mho22, I don't have any immediate ideas about this, but if you're interested, I am up for joining you for a screen share via WordPress.org Slack (assuming Slack huddles are supported there).

Either way, I have a few questions that might help us troubleshoot and/or reproduce your issue:

  • What OS are you using?
  • What browser version?
  • Do you see any relevant errors in the dev tools network tab?
  • Are you running with the latest commits from this repo?

@brandonpayton
Copy link
Member

@mho22, I wonder if this is related to #1196, where Firefox does not support loading a Service Worker script as an ES module.

@brandonpayton
Copy link
Member

It's puzzling how this could just be a problem with updating though.

@mho22
Copy link
Contributor Author

mho22 commented Apr 4, 2024

@brandonpayton sorry for the delay.

OS : Mac OS Sonoma 14.4.1 (23E224)
Browser : Google chrome Version 123.0.6312.87 (Build officiel) (arm64)
Network issue : index.ts canceled : service-worker.ts?type=module&worker_file:2
Git branch : curl-support

I only have to comment the line 45 in file register-service-worker.ts to make this work :

// Check if there's a new service worker available and, if so, enqueue
// the update:
//await registration.update();

So I suppose if you add a try catch it could maybe solve the issue ?

Edit: I found information on this link stating that the update() method is only available in secure contexts. Currently, I am loading this on localhost via HTTP. Perhaps this could be the explanation. We could consider adding a condition like this:

// Check if there's a new service worker available and, if so, enqueue
// the update:
if( registration.scope.includes( 'https://' ) ) await registration.update();

I am not entirely certain about the reason and solution, by the way.

@adamziel
Copy link
Collaborator

adamziel commented Apr 5, 2024

While that’s a good find, I’m also confused because I thought Service Workers in general are only allowed in secure contexts: #1098

Could it be that localhost is a special case where one can user service workers but not the update() method? But why would it only fail sometimes?

@brandonpayton
Copy link
Member

Thanks for the info, @mho22.

I just ran into this same issue in Chrome Canary (Version 125.0.6401.0 (Official Build) canary (x86_64)):
image

Edit: I found information on this link stating that the update() method is only available in secure contexts. Currently, I am loading this on localhost via HTTP. Perhaps this could be the explanation. We could consider adding a condition like this:

Could it be that localhost is a special case where one can user service workers but not the update() method? But why would it only fail sometimes?

@mho22 and @adamziel, localhost is indeed a special according to this:
https://w3c.github.io/webappsec-secure-contexts/#localhost

Section 6.3 of [RFC6761] lays out the resolution of localhost. and names falling within .localhost. as special, and suggests that local resolvers SHOULD/MAY treat them specially. For better or worse, resolvers often ignore these suggestions, and will send localhost to the network for resolution in a number of circumstances.

Given that uncertainty, user agents MAY treat localhost names as having potentially trustworthy origins if and only if they also adhere to the localhost name resolution rules spelled out in [let-localhost-be-localhost] (which boil down to ensuring that localhost never resolves to a non-loopback address).

This made me wonder about explicitly using the loopback address 127.0.0.1 instead of "localhost", and that did the trick. Chrome loaded local Playground successfully and presumably was able to update the service worker as part of the process.

I wonder if we can have npm run dev show http://127.0.0.1:5400/website-server/ instead of http://localhost:5400/website-server/ to avoid the possibility of this issue.

@brandonpayton
Copy link
Member

brandonpayton commented Apr 6, 2024

I wonder if we can have npm run dev show http://127.0.0.1:5400/website-server/ instead of http://localhost:5400/website-server/ to avoid the possibility of this issue.

I created PR #1209 to use 127.0.0.1 instead.

@mho22
Copy link
Contributor Author

mho22 commented Apr 6, 2024

@brandonpayton briliant! I suppose we can close this issue.

@mho22 mho22 closed this as completed Apr 6, 2024
adamziel pushed a commit that referenced this issue Apr 8, 2024
This PR fixes #1180 - Playground on localhost sometimes fails to load
due to failed service worker updates from "localhost".

## How is the problem addressed?

By switching from "localhost" to the explicit loopback address
"127.0.0.1". This avoids the case where "localhost" does not directly
resolve to a loopback address.

For reference:
https://w3c.github.io/webappsec-secure-contexts/#localhost
> Section 6.3 of
[[RFC6761]](https://w3c.github.io/webappsec-secure-contexts/#biblio-rfc6761)
lays out the resolution of localhost. and names falling within
.localhost. as special, and suggests that local resolvers SHOULD/MAY
treat them specially. For better or worse, resolvers often ignore these
suggestions, and will send localhost to the network for resolution in a
number of circumstances.
> 
> Given that uncertainty, user agents MAY treat localhost names as
having [potentially trustworthy
origins](https://w3c.github.io/webappsec-secure-contexts/#potentially-trustworthy-origin)
if and only if they also adhere to the localhost name resolution rules
spelled out in
[[let-localhost-be-localhost]](https://w3c.github.io/webappsec-secure-contexts/#biblio-let-localhost-be-localhost)
(which boil down to ensuring that localhost never resolves to a
non-loopback address).

## Testing Instructions

Run `npm run dev` and confirm the new dev server URL is
`http://127.0.0.1:5400/website-server/` and that local Playground loads
successfully in your browser.
@MocioF
Copy link

MocioF commented Apr 10, 2024

I'am having the same problem in Firefox asking for both http://localhost:5400 and http://127.0.0.1:5400

Firefox version is 115.9.1esr (64 bit)
built on Gentoo

errors are:

TypeError: ServiceWorker script at http://localhost:5400/service-worker.ts?type=module&worker_file for scope http://localhost:5400/ threw an exception during script evaluation. remote.html:69:12
    <anonima> remote.html:69

Uncaught (in promise) TypeError: ServiceWorker script at http://localhost:5400/service-worker.ts?type=module&worker_file for scope http://localhost:5400/ threw an exception during script evaluation. comlink.ts:259:8
Firefox non può stabilire una connessione con il server ws://localhost:5400/. client.ts:77:17

There is no issue in chrome 123.0.6312.105 (on the same linux machine).
In chrome playground works querying both http://localhost:5400 and http://127.0.0.1:5400

@bgrgicak
Copy link
Collaborator

Localhost still exists in some places it might be worth updating everything to 127.0.0.1.

@MocioF we also had this issue in Firefox before changing to 127.0.0.1.

@brandonpayton
Copy link
Member

@MocioF, I believe this is due to Firefox not yet supporting ES module-based service workers. See #330.

On playground.wordpress.net, the built service worker script does not contain any syntax specific to ES modules, so it works in Firefox. But during local dev with npm run dev, the service worker contains import statements that require ES module support, which Firefox does not yet provide for service workers.

@brandonpayton
Copy link
Member

Localhost still exists in some places it might be worth updating everything to 127.0.0.1.

In retrospect, it seems obvious that this search should have been done in the original PR. Thank you for bringing this up, @bgrgicak! I made a note to follow up on this.

@brandonpayton
Copy link
Member

I'm not sure switching to 127.0.0.1 did anything to fix this. Afterward, I continued to see ServiceWorker update errors in Chrome.

Now that we have merged #1849, I am no longer seeing these errors.

Since 127.0.0.1 seems like a more reliable loopback address than localhost for the reasons stated earlier in this issue, I think the change from localhost to 127.0.0.1 was OK anyway.

@brandonpayton
Copy link
Member

I'm not sure switching to 127.0.0.1 did anything to fix this. Afterward, I continued to see ServiceWorker update errors in Chrome.

Now that we have merged #1849, I am no longer seeing these errors.

Please disregard the above. It was incorrect. Switching to any other commit and running the dev server still reveals this issue. In practice, it's not too annoying because we don't edit the Service Worker too often, but I'm going to reopen this issue to track it.

@brandonpayton brandonpayton reopened this Oct 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Focus] Developer Tools [Type] Bug An existing feature does not function as intended
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

5 participants