Update as upsert does not work as expected on deleted rows
After a lot of banging my (+ Claude's) head against the wall, I've noticed some unexpected behavior:
Context:
Using the react native instantdb client library (v1.0.49).
Schema which uses a deterministic key like this:
key: i.string().unique().indexed()
Normally, when you issue an update, it will behave as an upsert (see docs at https://www.instantdb.com/docs/instaml#update-data). However, when you delete this data out-of-band (f.ex. through explorer), the same upsert (using the same key as before) will fail with a 'updating entities that don't exist '. This does not appear to be a race condition, this happens half an hour after deleting the entity manually f.ex. If the entity was never created before or not deleted, it all works as expected, doing a create or an update respectively.
Important: if we have an active subscription to the entity, this all works fine since the server delete is immediately propagated. This only happens when the client side state is stale, and we try to send an update before it got a chance to refresh.
The actual sequence to produce the (for me) unexpected behavior:
- mount screen, which issues an update (as upsert) to create a row with a deterministic key, let's call it A
- unmount (which removes the subscription to the entity)
- out-of-band deletion of row A (cleanup f.ex.)
- remount screen, which issues another update (as upsert) for key A, but this fails with 'Updating entities that don't exist'
Also see the code below for this sequence (although I'm using subscribeQuery to prevent having to mount/unmount/remount)
This likely has something to do with instantdb cache, because if add a 'cleanup instantdb storage' right after the out-of-band deletion of row A, there are no errors.
Not sure if this is expected behavior, but took me quite some time to figure out why my update upserts were not working in some cases.
Happy to give additional information if needed!
Source: instantdb/instant