Dexie.js: Firefox 67: "InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable"

Created on 26 May 2019  Â·  12Comments  Â·  Source: dfahlander/Dexie.js

I'm struggling a bit to get Dexie to work correctly. It's probably me who's _holding it wrong_. I've tried to integrate the database-opening procedure described in the docs into my setup, through a dedicated method:

  private async openDatabase(version: number, stores: DexieStores): Promise<Dexie|null> {
    let db: Dexie = new Dexie(environment.database.name, { autoOpen: false });

    console.debug(`Trying to open local database "${environment.database.name}" with version ${version} and the following stores:`);
    console.debug(stores);
    db.version(version).stores(stores);

    try {
      console.debug('Opening local database ...');
      await db.open();

      console.debug('Adding observer to local database ...');
      db = await this.observeDatabase(db);

      return db;
    } catch(err) {
      console.error('Could not open local database:');
      console.error(err);

      console.debug('Will delete the local database now.');
      Dexie.delete(environment.database.name);

      return null;
    }

    return db;
  }

However, I'm getting the following warning when running that method:

Unhandled rejection: InvalidStateError: A mutation operation was attempted on a database that did not allow mutations.
Transaction/<@http://localhost:4200/vendor.js:152539:63
nativeAwaitCompatibleWrap/<@http://localhost:4200/vendor.js:151064:23
callListener@http://localhost:4200/vendor.js:150753:19
endMicroTickScope@http://localhost:4200/vendor.js:150834:25
wrap/<@http://localhost:4200/vendor.js:150901:17
wrapFn@http://localhost:4200/polyfills.js:13802:39
./node_modules/zone.js/dist/zone.js/</ZoneDelegate.prototype.invokeTask@http://localhost:4200/polyfills.js:12944:31
onInvokeTask@http://localhost:4200/vendor.js:82607:33
./node_modules/zone.js/dist/zone.js/</ZoneDelegate.prototype.invokeTask@http://localhost:4200/polyfills.js:12943:60
./node_modules/zone.js/dist/zone.js/</Zone.prototype.runTask@http://localhost:4200/polyfills.js:12716:47
./node_modules/zone.js/dist/zone.js/</ZoneTask.invokeTask@http://localhost:4200/polyfills.js:13019:34
invokeTask@http://localhost:4200/polyfills.js:14214:14
globalZoneAwareCallback@http://localhost:4200/polyfills.js:14240:17

From previous: 
then@http://localhost:4200/vendor.js:150477:22
Transaction@http://localhost:4200/vendor.js:152530:26
Dexie/this._createTransaction@http://localhost:4200/vendor.js:151538:16
overrideCreateTransaction/<@http://localhost:4200/vendor.js:148790:34
enterTransactionScope/<@http://localhost:4200/vendor.js:151919:32
nativeAwaitCompatibleWrap/<@http://localhost:4200/vendor.js:151064:23
callListener@http://localhost:4200/vendor.js:150747:19
endMicroTickScope@http://localhost:4200/vendor.js:150834:25
wrap/<@http://localhost:4200/vendor.js:150901:17
wrapFn@http://localhost:4200/polyfills.js:13802:39
./node_modules/zone.js/dist/zone.js/</ZoneDelegate.prototype.invokeTask@http://localhost:4200/polyfills.js:12944:31
onInvokeTask@http://localhost:4200/vendor.js:82607:33
./node_modules/zone.js/dist/zone.js/</ZoneDelegate.prototype.invokeTask@http://localhost:4200/polyfills.js:12943:60
./node_modules/zone.js/dist/zone.js/</Zone.prototype.runTask@http://localhost:4200/polyfills.js:12716:47
./node_modules/zone.js/dist/zone.js/</ZoneTask.invokeTask@http://localhost:4200/polyfills.js:13019:34
invokeTask@http://localhost:4200/polyfills.js:14214:14
globalZoneAwareCallback@http://localhost:4200/polyfills.js:14240:17

From previous: InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable
supplyIdbStore@http://localhost:4200/vendor.js:152057:59
_promise/p<@http://localhost:4200/vendor.js:152649:30
executePromiseTask@http://localhost:4200/vendor.js:150649:9
Promise@http://localhost:4200/vendor.js:150466:5
_promise@http://localhost:4200/vendor.js:152648:25
getTransaction@http://localhost:4200/vendor.js:152048:27
getIDBObjectStore@http://localhost:4200/vendor.js:152059:25
_read@http://localhost:4200/vendor.js:153197:31
toArray@http://localhost:4200/vendor.js:153272:29
first@http://localhost:4200/vendor.js:153358:38
startObserving/</<@http://localhost:4200/vendor.js:149446:22
enterTransactionScope/</promiseFollowed<@http://localhost:4200/vendor.js:151939:45
follow/</<@http://localhost:4200/vendor.js:150634:17
usePSD@http://localhost:4200/vendor.js:151045:16
newScope@http://localhost:4200/vendor.js:150942:14
follow/<@http://localhost:4200/vendor.js:150621:20
executePromiseTask@http://localhost:4200/vendor.js:150649:9
Promise@http://localhost:4200/vendor.js:150466:5
follow@http://localhost:4200/vendor.js:150620:16
enterTransactionScope/<@http://localhost:4200/vendor.js:151937:47
nativeAwaitCompatibleWrap/<@http://localhost:4200/vendor.js:151064:23
callListener@http://localhost:4200/vendor.js:150747:19
endMicroTickScope@http://localhost:4200/vendor.js:150834:25
wrap/<@http://localhost:4200/vendor.js:150901:17
wrapFn@http://localhost:4200/polyfills.js:13802:39
./node_modules/zone.js/dist/zone.js/</ZoneDelegate.prototype.invokeTask@http://localhost:4200/polyfills.js:12944:31
onInvokeTask@http://localhost:4200/vendor.js:82607:33
./node_modules/zone.js/dist/zone.js/</ZoneDelegate.prototype.invokeTask@http://localhost:4200/polyfills.js:12943:60
./node_modules/zone.js/dist/zone.js/</Zone.prototype.runTask@http://localhost:4200/polyfills.js:12716:47
./node_modules/zone.js/dist/zone.js/</ZoneTask.invokeTask@http://localhost:4200/polyfills.js:13019:34
invokeTask@http://localhost:4200/polyfills.js:14214:14
globalZoneAwareCallback@http://localhost:4200/polyfills.js:14240:17

From previous: 
Transaction@http://localhost:4200/vendor.js:152526:28
Dexie/this._createTransaction@http://localhost:4200/vendor.js:151538:16
overrideCreateTransaction/<@http://localhost:4200/vendor.js:148790:34
enterTransactionScope/<@http://localhost:4200/vendor.js:151919:32
nativeAwaitCompatibleWrap/<@http://localhost:4200/vendor.js:151064:23
callListener@http://localhost:4200/vendor.js:150747:19
endMicroTickScope@http://localhost:4200/vendor.js:150834:25
wrap/<@http://localhost:4200/vendor.js:150901:17
wrapFn@http://localhost:4200/polyfills.js:13802:39
./node_modules/zone.js/dist/zone.js/</ZoneDelegate.prototype.invokeTask@http://localhost:4200/polyfills.js:12944:31
onInvokeTask@http://localhost:4200/vendor.js:82607:33
./node_modules/zone.js/dist/zone.js/</ZoneDelegate.prototype.invokeTask@http://localhost:4200/polyfills.js:12943:60
./node_modules/zone.js/dist/zone.js/</Zone.prototype.runTask@http://localhost:4200/polyfills.js:12716:47
./node_modules/zone.js/dist/zone.js/</ZoneTask.invokeTask@http://localhost:4200/polyfills.js:13019:34
invokeTask@http://localhost:4200/polyfills.js:14214:14
globalZoneAwareCallback@http://localhost:4200/polyfills.js:14240:17

It is then followed by this error:

{…}
​
_e: Error: ""
    getErrorWithStack dexie.es.js:311
    DexieError dexie.es.js:440
    mapError dexie.es.js:470
    handleRejection dexie.es.js:954
    executePromiseTask dexie.es.js:946
    Promise dexie.es.js:740
    _promise dexie.es.js:2922
    getTransaction dexie.es.js:2322
    getIDBObjectStore dexie.es.js:2333
    _read dexie.es.js:3471
    toArray dexie.es.js:3546
    first dexie.es.js:3632
    startObserving dexie-observable.es.js:723
    promiseFollowed dexie.es.js:2213
    follow dexie.es.js:908
    usePSD dexie.es.js:1319
    newScope dexie.es.js:1216
    follow dexie.es.js:895
    executePromiseTask dexie.es.js:923
    Promise dexie.es.js:740
    follow dexie.es.js:894
    enterTransactionScope dexie.es.js:2211
    nativeAwaitCompatibleWrap dexie.es.js:1338
    callListener dexie.es.js:1021
    endMicroTickScope dexie.es.js:1108
    wrap dexie.es.js:1175
    Angular 8
​
_promise: Object { _lib: true, _numPrev: 0, _state: false, … }
​
inner: DOMException: "An attempt was made to use an object that is not, or is no longer, usable"
​
message: "An attempt was made to use an object that is not, or is no longer, usable"
​
name: "InvalidStateError"
​
stack: "InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable\nsupplyIdbStore@http://localhost:4200/vendor.js:152057:59\n_promise/p<@http://localhost:4200/vendor.js:152649:30\nexecutePromiseTask@http://localhost:4200/vendor.js:150649:9\nPromise@http://localhost:4200/vendor.js:150466:5\n_promise@http://localhost:4200/vendor.js:152648:25\ngetTransaction@http://localhost:4200/vendor.js:152048:27\ngetIDBObjectStore@http://localhost:4200/vendor.js:152059:25\n_read@http://localhost:4200/vendor.js:153197:31\ntoArray@http://localhost:4200/vendor.js:153272:29\nfirst@http://localhost:4200/vendor.js:153358:38\nstartObserving/</<@http://localhost:4200/vendor.js:149446:22\nenterTransactionScope/</promiseFollowed<@http://localhost:4200/vendor.js:151939:45\nfollow/</<@http://localhost:4200/vendor.js:150634:17\nusePSD@http://localhost:4200/vendor.js:151045:16\nnewScope@http://localhost:4200/vendor.js:150942:14\nfollow/<@http://localhost:4200/vendor.js:150621:20\nexecutePromiseTask@http://localhost:4200/vendor.js:150649:9\nPromise@http://localhost:4200/vendor.js:150466:5\nfollow@http://localhost:4200/vendor.js:150620:16\nenterTransactionScope/<@http://localhost:4200/vendor.js:151937:47\nnativeAwaitCompatibleWrap/<@http://localhost:4200/vendor.js:151064:23\ncallListener@http://localhost:4200/vendor.js:150747:19\nendMicroTickScope@http://localhost:4200/vendor.js:150834:25\nwrap/<@http://localhost:4200/vendor.js:150901:17\nwrapFn@http://localhost:4200/polyfills.js:13802:39\n./node_modules/zone.js/dist/zone.js/</ZoneDelegate.prototype.invokeTask@http://localhost:4200/polyfills.js:12944:31\nonInvokeTask@http://localhost:4200/vendor.js:82607:33\n./node_modules/zone.js/dist/zone.js/</ZoneDelegate.prototype.invokeTask@http://localhost:4200/polyfills.js:12943:60\n./node_modules/zone.js/dist/zone.js/</Zone.prototype.runTask@http://localhost:4200/polyfills.js:12716:47\n./node_modules/zone.js/dist/zone.js/</ZoneTask.invokeTask@http://localhost:4200/polyfills.js:13019:34\ninvokeTask@http://localhost:4200/polyfills.js:14214:14\nglobalZoneAwareCallback@http://localhost:4200/polyfills.js:14240:17\n\nFrom previous: \n_promise@http://localhost:4200/vendor.js:152648:25\ngetTransaction@http://localhost:4200/vendor.js:152048:27\ngetIDBObjectStore@http://localhost:4200/vendor.js:152059:25\n_read@http://localhost:4200/vendor.js:153197:31\ntoArray@http://localhost:4200/vendor.js:153272:29\nfirst@http://localhost:4200/vendor.js:153358:38\nstartObserving/</<@http://localhost:4200/vendor.js:149446:22\nenterTransactionScope/</promiseFollowed<@http://localhost:4200/vendor.js:151939:45\nfollow/</<@http://localhost:4200/vendor.js:150634:17\nusePSD@http://localhost:4200/vendor.js:151045:16\nnewScope@http://localhost:4200/vendor.js:150942:14\nfollow/<@http://localhost:4200/vendor.js:150621:20\nexecutePromiseTask@http://localhost:4200/vendor.js:150649:9\nPromise@http://localhost:4200/vendor.js:150466:5\nfollow@http://localhost:4200/vendor.js:150620:16\nenterTransactionScope/<@http://localhost:4200/vendor.js:151937:47\nnativeAwaitCompatibleWrap/<@http://localhost:4200/vendor.js:151064:23\ncallListener@http://localhost:4200/vendor.js:150747:19\nendMicroTickScope@http://localhost:4200/vendor.js:150834:25\nwrap/<@http://localhost:4200/vendor.js:150901:17\nwrapFn@http://localhost:4200/polyfills.js:13802:39\n./node_modules/zone.js/dist/zone.js/</ZoneDelegate.prototype.invokeTask@http://localhost:4200/polyfills.js:12944:31\nonInvokeTask@http://localhost:4200/vendor.js:82607:33\n./node_modules/zone.js/dist/zone.js/</ZoneDelegate.prototype.invokeTask@http://localhost:4200/polyfills.js:12943:60\n./node_modules/zone.js/dist/zone.js/</Zone.prototype.runTask@http://localhost:4200/polyfills.js:12716:47\n./node_modules/zone.js/dist/zone.js/</ZoneTask.invokeTask@http://localhost:4200/polyfills.js:13019:34\ninvokeTask@http://localhost:4200/polyfills.js:14214:14\nglobalZoneAwareCallback@http://localhost:4200/polyfills.js:14240:17\n"
​
<get stack()>: function get()
​
<prototype>: Object { stack: "", … }
app.component.ts:74:14
    openDatabase app.component.ts:74
    step tslib.es6.js:97
    verb tslib.es6.js:78
    rejected tslib.es6.js:69
    Angular 13

Not sure what could cause this issue. I'd like to point out that this only occurs in Firefox. In Chrome it works flawlessly. Firefox is not running in private mode, content blocking settings are set to "Standard", it allows cookies and it doesn't look like there are other restrictions in place.

Most helpful comment

@dfahlander We are experiencing an analogous issue: since Firefox 67, when Developer Tools window is open, all Dexie calls fail with InvalidStateError. If Developer Tools is not open, the app works fine. This did not happen in previous versions of Firefox. I guess this is a Firefox-related issue.

All 12 comments

I ran another test with fresh browsers. The Firefox issue remains, however, Chrome, as well as Safari, showed this error on the very first launch of the site:

[Error] DexieError

_e: Error

_promise: Promise {_listeners: [], onuncatched: function, _lib: false, _PSD: Object, _stackHolder: Error, …}

inner: NotFoundError: Failed to execute 'transaction' on 'IDBDatabase': One of the specified object stores was not found.

message: "Failed to execute 'transaction' on 'IDBDatabase': One of the specified object stores was not found."

name: "NotFoundError"

stack: 

DexieError Prototype

    (anonymous function) (main.js:232)
    step (vendor.js:203437)
    rejected (vendor.js:203409)
    onInvoke (vendor.js:82616)
    run (polyfills.js:12671)
    (anonymous function) (polyfills.js:13431)
    onInvokeTask (vendor.js:82607)
    runTask (polyfills.js:12716)
    drainMicroTaskQueue (polyfills.js:13122)
    invokeTask (polyfills.js:13023)
    invokeTask (polyfills.js:14214)
    globalZoneAwareCallback (polyfills.js:14240)

After reloading the page, the error was gone in both browsers and everything was working as expected.

Maybe you are calling that method in parallell some how.

My recommendation is usually do just declare the db instance in a module and let it take care of opening when needed, See https://dexie.org/docs/Tutorial/Understanding-the-basics

Your call to observeDatabase could be done in db.on.ready().

I'm seeing the same thing on Firefox 67. Worked fine in older versions, works fine in Chrome.

if it can help , ive just deleted an issue with FF67 that i believed resolve but in fact not
and ive found why

the request
await this.$mydb.MYTAB.where('from').equals(taskRef).or('to').equals(taskRef).toArray()

Chrome , Localhost & file:// = NO ERROR
FF67 Localhost = NO ERROR
FF67 file:// = Unhandled promise rejection - A request was placed against a transaction which is currently not active, or which is finished.

but if i reduce the request (removing the "or")
await this.$mydb.MYTAB.where('from').equals(taskRef).toArray()

FF67 file:// = NO ERROR

so , i think that the "or" add a promise and FF67 do not handle/understand it

But may im totally wrong, was just in case it can help

@ledahu I tried all the unit tests in FF67, using local file system (file:// instead of http://) but had no issues there. What could differ in your environment, could be what data you have on the different origins file:// and localhost. So one question is: From where do you get 'taskRef'? If it comes from an earlier query, could it be the case that taskRef is null, undefined or other non-indexable type? That would lead to error when using it as an arg to equals().

I'm also curious about whether taskRef is a string/number/array or a binary key (ArrayBuffer/Uint8Array, etc).

@dfahlander : Same problem here in production (and localhost, but in production with real site and conf too) with firefox 67 only (before that worked)

function initBDD() {
  window.sbk_db = new Dexie('sbook_dbase', {autoOpen: true});
  window.sbk_db.version(1).stores({
    sbook_info: "++id,datesub",
  });

window.sbk_db.on('ready', function () {
//populate
});

// Open Or Die -> execute ready !
  window.sbk_db.open().catch(function (err) {
    console.log(err);
  });
}

That's worked yesterday... Update to 67 and today :
```
OpenFailedError: InvalidStateError An attempt was made to use an object that is not, or is no longer, usable
InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable


Unhandled rejection: InvalidStateError: A mutation operation was attempted on a database that did not allow mutations.
InvalidStateError: A mutation operation was attempted on a database that did not allow mutations.

From previous:
L/ehttp://localhost/scribbook-app/modext/dexie/dexie-observable.min.js?v=1552036204:1:5942
```

Is there a workaround ?

(PS : I tried without dexie-observable : KO in the same way)

I tried many way opening, using from documentation but finally FF67 + Dexie = KO for me :(

Update from me and users : this seem to be "random" or "inconsistency". Sometimes that work, load the page but next bim error. Maybe linked to new optimizations "memory and speed" of the v67 ?

Update from me and users : this seem to be "random" or "inconsistency". Sometimes that work, load the page but next bim error. Maybe linked to new optimizations "memory and speed" of the v67

idem for me, i love when you rebuild/reload and its work fine, but in fact it was a random succes ;)
=> i have the same feeling : its a FF67 speed issue

Any idea to fix this ? Wait the next FF update ?

@dfahlander We are experiencing an analogous issue: since Firefox 67, when Developer Tools window is open, all Dexie calls fail with InvalidStateError. If Developer Tools is not open, the app works fine. This did not happen in previous versions of Firefox. I guess this is a Firefox-related issue.

I confirm : without Developer Tools Open : it's OK (sorry I hadn't make the link before)
But maybe there are warning that we can't see so...
It's worse with dexie-observable (warning in loop infinite in localhost)

Dupe of https://github.com/dfahlander/Dexie.js/issues/831

This will get fixed in Firefox 69 :crossed_fingers:

Was this page helpful?
0 / 5 - 0 ratings