Angular service worker is in SAFE_MODE Angular service worker is in SAFE_MODE angular angular

Angular service worker is in SAFE_MODE


Update

This will be fixed as of Angular version 8.2.14. Below workarounds are only required with older versions.

 


 

Old workarounds for < 8.2.14

It seems this is a well known bug in the Angular service worker and that we may expect a patch / working version at some point. Most information can be found in issue 25611 as shobhit vaish already stated.

However, if you are looking for a solution now or you are going to stick with an older Angular 7/8 version longer, which maybe will not get patched soon, I will try to sum up the currently known workarounds. (Also they may not qualify as "proper solution"...)

Patching ngsw-worker.js

You can patch your ngsw-worker.js file either after your ng run app:build:production where it will typically reside in the www folder inside your project (if you haven't changed the Angular outputPath). Or you can patch it before your build inside node_modules/@angular/service-worker.

Depending on how often you build your app you could do it simply manually (i.e. with a text editor of your choice) or you write a script for example with the help of sed.

Now you have two options:

1. Patching handleMessage()

Search for

        handleMessage(msg, from) {            return __awaiter$5(this, void 0, void 0, function* () {

And replace it with

        handleMessage(msg, from) {            return __awaiter$5(this, void 0, void 0, function* () {                if (this.initialized === null) {                    this.initialized = this.initialize();                }                try {                    yield this.initialized;                }                catch (e) {                    this.state = DriverReadyState.SAFE_MODE;                    this.stateMessage = `Initialization failed due to handleMessage() error: ${errorToString(e)}`;                }

Depending on your @angular/service-worker version the signature of handleMessage() may look different for you and you could write a more sophisticated catch but hopefully / probably it would never reach the catch block anyways.
This patch basically is what is suggested in a comment by gkalpak and most likely the official fix will also be something like this.

2. Patching initialize()

Search for

                try {                    // Read them from the DB simultaneously.                    [manifests, assignments, latest] = yield Promise.all([                        table.read('manifests'),                        table.read('assignments'),                        table.read('latest'),                    ]);

And replace it with

                try {                    // Read them from the DB simultaneously.                    [manifests, assignments, latest] = yield Promise.all([                        table.read('manifests'),                        table.read('assignments'),                        table.read('latest'),                    ]);                    if (latest.latest === null) throw new Error('Error latest.latest is null for what ever reason...');

With this you will ensure that the catch block of initialize() will actually run and prevent the service worker from entering SAFE_MODE. However this may not be as reliable as the first patch but could also work for service workers which are already in SAFE_MODE due to this problem. It was proposed in a comment by hsta.

Working around the problem in your Angular app

If you don't want to mess around with the ngsw-worker.js you can try to detect the state of the service worker by fetching your-app.domain/ngsw/state from within your Angular app and if it is in SAFE_MODE (could be checked for example with a simple regex search) you can try to reset it by deleting all items from the cache storage and then unregistering the service worker. The idea to this was proposed in a comment by mattlewis92 and approved as probably working hack in a comment by gkalpak.

Temporary working around the problem manually

As shobhit vaish already found out, you can also manually resolve the issue. Next to the possibility which is already stated in the original post you can also do this in the dev tools of chrome based browser under "Application" -> "Clear storage", selecting "Unregister service workers" and hit "Clear site data". Obviously the problem can and probably will come back on future updates and will not help much for normal users. But it may be handy if you as developer just want to resolve it quickly at the moment.