fulcro

Eric Dvorsak 2025-03-12T14:56:14.269189Z

Isn't com.fulcrologic.fulcro.algorithms.merge/mark-missing-impl considering nil values as missing? I've already been bitten a few time by a nil value that is normal and makes sense in my business logic but is turned into a :com.fulcrologic.fulcro.algorithms.merge/not-found by fulcro

tony.kay 2025-03-12T17:11:11.677859Z

nil IS a value from Fulcro’s perspective. You are literally saying “this value is nil”…which means it should overwrite in the db

tony.kay 2025-03-12T17:11:16.642519Z

NOT missing

tony.kay 2025-03-12T17:12:04.280919Z

If the server has no opinion of the value of a prop, then it should not return the key. By including the key the server is making an assertion that IT KNOWS the value to be nil, and is therefore not “missing”…it’s nil

tony.kay 2025-03-12T17:12:44.699699Z

But also if the client ASKED for it and the server doesn’t include it, the opinion is that the value was asked for and not received, and therefore should be removed

tony.kay 2025-03-12T17:13:21.689269Z

See the merge documentation in the book. This was very carefully designed to do the “best” it could do with information provided in a distributed system sense.

Eric Dvorsak 2025-03-12T17:24:54.847719Z

Yeah what you are saying is consistent with what I would expect as well, but what I get is that when the value of a key is nil the nil value is replaced by this ::not-found

tony.kay 2025-03-12T18:20:06.218079Z

in the final db?

tony.kay 2025-03-12T18:20:11.810459Z

that should be swept

tony.kay 2025-03-12T18:20:30.942449Z

mark-missing does that, and then a final sweep stage removes the keys.

tony.kay 2025-03-12T18:20:46.932529Z

normalization can cause overwrites as it progresses, so that’s why it is in stages

Eric Dvorsak 2025-03-12T19:51:25.902779Z

In the network response the value is nil but then in the app db it's gone

Eric Dvorsak 2025-03-12T19:53:36.933209Z

so it's actually the step that saves to app db that is losing the value

Eric Dvorsak 2025-03-12T19:55:19.168789Z

query is: [:dialogue.session/id ... :dialogue.session/evaluation {:dialogue.session/messages (comp/get-query DialogueMessage)}] and for DialogueMessage: [:dialogue.message/id :dialogue.message/role :dialogue.message/topic-id :dialogue.message/created-at :dialogue.message/text :dialogue.message/image-urls]

tony.kay 2025-03-12T21:43:59.223119Z

but isn’t that what you expect?

tony.kay 2025-03-12T21:44:24.194959Z

value is nil means the server has no value

tony.kay 2025-03-12T21:46:13.053249Z

Think over time: time 1 - you had a value time 2 - you don’t have the vlue (but you query for it) At time 2 my code is evaluating the following cases: • You asked for it • It didn’t arrive • I need to make sure that the value in the app db is no longer there • So, I dissoc the key I see this as “safe” because if the UI queries for the prop, it’ll be nil, so there’s no reason to store nil in the db.

Eric Dvorsak 2025-03-17T10:53:18.440229Z

In the api response it's nil

Eric Dvorsak 2025-03-17T10:53:32.793059Z

In fulcro inspect db it's gone:

Eric Dvorsak 2025-03-17T10:54:22.743829Z

in the defsc component it's ::not-found

tony.kay 2025-03-17T12:40:44.189709Z

That makes no sense to me

tony.kay 2025-03-17T12:41:59.511459Z

That would mean it's in db->tree... Are you using premerge?

sheluchin 2025-07-17T23:23:10.563829Z

@yenda1 did you get to the bottom of this? I'm running into the same thing. The response from the server is nil but in my component it shows up as :com.fulcrologic.fulcro.algorithms.merge/not-found. I am using pre-merge in the parent component and a Pathom placeholder like :>/stuff to spread an entity out across a few defsc's.

Eric Dvorsak 2025-03-13T09:55:13.076589Z

but the value is not missing, the value is nil , the server did return the value nil for that key. And the issue is that instead of being nil in the component, the value is then ::fulcro-merge/not-found In pathom when you return nil for a key it means the value was found and is nil, pathom stops searching for the value. not-found would be ::pco/unknown-value and pathom will keep trying other resolvers (if there is any)

tony.kay 2025-03-13T19:28:20.063829Z

Ah. I see. I’m not sure why not-found isn’t stripped by the post processing internally. I really don’t have time to diagnose that at the moment, but I would agree that the m/not-found keys should not be ending up in your client db.

tony.kay 2025-03-13T19:29:18.208969Z

You’re using straight vanilla df/load, network middleware, etc.?

Eric Dvorsak 2025-03-13T19:29:25.414029Z

They don't end up in the client db they end up in the components that query for it

tony.kay 2025-03-13T19:29:48.521199Z

props = Query(db)

tony.kay 2025-03-13T19:30:02.064149Z

so the MUST be in the db…or are you saying this is transient behavior

tony.kay 2025-03-13T19:30:11.594719Z

where you see them flash that value during normalization?

tony.kay 2025-03-13T19:31:17.973229Z

(like a render happens in the middle of the normalization/mark/sweep process)

tony.kay 2025-03-13T19:36:26.907819Z

data_fetch.cljc line 143 is the load processing. It marks missing, then processed the merge in a single swap, and the merge inside of that does the sweep. It should not be possible to see transient problems there (js is single-threaded…the merge/sweep happens in a single swap)

Eric Dvorsak 2025-07-21T11:09:19.232299Z

No we ended up checking for the value :com.fulcrologic.fulcro.algorithms.merge/not-found as a workaround because we ran out of time

Eric Dvorsak 2025-07-21T11:10:19.764319Z

This issue and how to deal with missing entities are the 2 dark passengers in our project, they occasionally resurface as the root cause of bugs

sheluchin 2025-07-21T13:03:28.590949Z

Thanks. I went with the workaround too because I couldn't figure it out within the time box.