pathom

Jakub Holý (HolyJak) 2023-03-17T19:31:51.432519Z

I have a mystery. Pathom cannot find an attribute in one context while it can find it in another. I have a resolver whose one input is {:order-line/product [ {:product/production-method [:production-method/num-id]} ]} and it fails with Insufficient data calling resolver due to > :missing {:order-line/product {:product/production-method {:production-method/num-id {}}}}}, When I simplify the input requirement to {:order-line/product [:product/production-method]} then inside the resolver I see the value of that is {:production-method/id #uuid "a0269c9d-63a1-4e14-afa3-08f81ab0c002"} So yes, there is not num-id because there is only the id of the entity. But when I ask Pathom to go from the id to num-id, it manages it just fine:

; EQL explorer
[{[:production-method/id #uuid "a0269c9d-63a1-4e14-afa3-08f81ab0c002"]
  [:production-method/num-id]}]
; =>
;{[:production-method/id #uuid "a0269c9d-63a1-4e14-afa3-08f81ab0c002"]
; {:production-method/num-id 2}}
So why is Pathom easily able to resolve :production-method/id -> :production-method/num-id but is not able to supply the num-id to a resolver, even though it can give it the :production-method/id ?! How to troubleshoot this? 🙏

✅ 1
wilkerlucio 2023-03-30T21:10:39.703049Z

@holyjak hey man, just wanna say sorry for the delay on this one, I didn't forgot about it, I'm on the last weeks of renovation in my apt and that's been very madness time to me, I hope this will be over by next week and I'll have enough head space to get to it

Jakub Holý (HolyJak) 2023-03-31T08:10:25.328219Z

No problem! I know you do this as a volunteer, in your free time. And I have a workaround so no big deal for me. Good luck with the renovation, I know how those are!

Jakub Holý (HolyJak) 2023-03-23T16:23:03.203629Z

@wilkerlucio Not exactly sure what to look for 😅 but it seems to work - run-capturing returns lot of data and running reproduce fails with the same error as my original query. BTW I will make an issue for the problem I reported so that I have a good way to track it. Hope it is ok!

caleb.macdonaldblack 2023-03-17T20:10:53.835989Z

A Pathom graph can be unintentionally constructed is such a way to cause the issue you’re having. In this example, it’s intuitive to think that Pathom could return both child and age at the same time. But Pathom can’t merge nested entities, so it only goes down one path.

caleb.macdonaldblack 2023-03-17T20:13:33.876509Z

While this might not explain your specific issue, it does highlight how easy it can be to make a mistake without realising it. You would have to figure out what path pathom is trying to take in your query that doesnt work. You’ll have to do this with lenient mode and the pathom vis too. You can also inspect the plan and execution metadata but it’s harder to grok.

caleb.macdonaldblack 2023-03-17T20:14:21.572839Z

Other easy things to look for are resolvers that describe their output as just :product/production-method , without providing any nested information.

caleb.macdonaldblack 2023-03-17T20:15:54.117749Z

Also I’ve run into similar issues that i’ve resolved by updating Pathom to the latest version.

Jakub Holý (HolyJak) 2023-03-17T20:19:25.713679Z

I see. Thank you!

caleb.macdonaldblack 2023-03-17T20:19:54.102449Z

Let me know how you go. I’ve run into this sort of stuff heaps

Jakub Holý (HolyJak) 2023-03-17T20:21:17.226459Z

Will do!

2023-03-17T22:30:05.500839Z

Pathom resolver nested input specs are selections not queries. They can select among the nested keys already present in the input map, but they do not trigger a query/resolution of nested attributes that are reachable but not yet present in the input map.

2023-03-17T22:37:44.580889Z

One way I've tried to tackle this problem is to simplify the input spec to the outer entity only, then inside the resolver body I issue a nested query for the nested attrs:

(defresolver my-resolver
  [env input]
  {::pco/input [{:order-line/product [:product/production-method]}]}
  (let [num-id (p.eql/process-one env (get-in input [:order-line/product :product/production-method]) :production-method/num-id)]
    ...))

pfeodrippe 2023-03-18T00:07:18.224529Z

Hey @ben.grabow, in Pathom 3, nested queries in resolver inputs can call new resolvers if needed (just like a normal query), https://pathom3.wsscode.com/docs/resolvers#nested-inputs. Or maybe you are talking about something different, let me know

2023-03-18T00:11:31.350379Z

@pfeodrippe I've tried that before and it didn't work how the docs describe, but maybe I used it wrong. I'll go back and try again.

👍 1
pfeodrippe 2023-03-18T00:13:45.532699Z

Got it, yeah, I use it a lot in may daily job and it works as expected, if you have some example that does not work, you can ping me o/

2023-03-18T00:14:12.250839Z

Thank you!

Jakub Holý (HolyJak) 2023-03-20T16:43:12.220449Z

I'll see if I get time tonight!

Jakub Holý (HolyJak) 2023-03-18T16:50:20.704169Z

FYI I got it working. It turns out that I did not read the (verbose) output from Pathom correctly. The real problem was with another input to my resolver, that lacked some dependencies. I just have to troubleshoot Pathom more to learn what to look for… . Possibly there was also some other problem I unwittingly fixed 🤷

Jakub Holý (HolyJak) 2023-03-18T17:09:48.655269Z

Actually, it is more interesting than I thought. While this EQL works (notice catalogue-number is derived among others via order-line/id -> order/id -> …, and order-line/id -> order-line/product -> product/production-method -> :production-method/num-id):

[{[:order-line/id 123]
  [:order-line/catalogue-number]}]
; => {... {:order-line/catalogue-number "0002 0001"}} ; yay!
If I add another attribute, :order-line/label-count - which is derived from order-line/package-count and order-line/product -> product/labels-per-package then suddenly catalogue number starts failing:
{[:order-line/id 123]
 {:order-line/label-count 950}} ; booo, no more cat. number! 😭 
So here I have 2 attributes that depend on order-line/product’s details, and that somehow do not play nicely together. Perhaps it is the problem Caleb suggested, that those two attributes open two possible paths for Pathom and it can only take one of them?

caleb.macdonaldblack 2023-03-18T17:11:04.542649Z

@holyjak You can merge those paths into one. It’s not ideal but it should work

Jakub Holý (HolyJak) 2023-03-18T17:14:10.255029Z

What do you mean? Make a dedicated single resolver that can resolve both?

caleb.macdonaldblack 2023-03-18T17:14:37.253619Z

Yeah

👍 1
caleb.macdonaldblack 2023-03-18T17:18:00.893869Z

For some more insight, Pathom will treat nested data as seperate entities, even if the parent keyword is the same. It won’t merge them.

caleb.macdonaldblack 2023-03-18T17:19:42.078669Z

For all it knows path A returns an entity with attribute X and path B returns an entity with attribute Y. It sees them as two seperate entities. You can either get X or Y. Not both. Because no path resolves an entity with both. IMO this isn’t ideal. Maybe it’s not possible but I would love to try because it opens up so many possibilities.

Jakub Holý (HolyJak) 2023-03-18T17:21:08.890869Z

I guess I start to understand it. I have 2 derived attributes (`catalogue-number` and label-count) that both depend on a third sibling, :order-line/`product` , but each one needs a different subset of product’s properties. And Pathom is not able to merge those two subqueries to request both subsets at once. Instead, it follows down one path and end up with a partial product in the environment. Then when it gets to resolving the 2nd derived attribute (cat.nr.), it thinks “nice, I already have a product, no need to resolve it” but it does not have the necessary data, and Pathom stops at that. Is that somewhat correct?

Jakub Holý (HolyJak) 2023-03-18T17:21:37.843839Z

Ah yeh, you just posted that while I was typing > path A returns an entity with attribute X and path B returns an entity with attribute Y. It sees them as two seperate entities.

caleb.macdonaldblack 2023-03-18T17:22:49.219709Z

That’s exactly how I understand it

👍 1
Jakub Holý (HolyJak) 2023-03-18T17:23:35.360399Z

@wilkerlucio What Caleb and me describe just above is a limitation of Pathom that really surprised me. Could you be so kind and point me to where it is documented? And do you think there are ways to alleviate it in the future? Thank you!

caleb.macdonaldblack 2023-03-18T17:24:05.345959Z

@holyjak @wilkerlucio Agreed, this surprises me also.

caleb.macdonaldblack 2023-03-18T17:25:36.280779Z

IMO, a keyword with a nested entity should be treated like a relationship and not a value, and Pathom should auto merge (the data or the resolver) them because they’re semantically the same thing. This does get tricker however with one-many relationships. Pathom would need to track entity ids for this sort of thing to work

💯 2
caleb.macdonaldblack 2023-03-18T17:26:08.636039Z

And I’m sure there are other nuances.

Jakub Holý (HolyJak) 2023-03-18T17:26:23.592579Z

It is little more complicated in my case. The product itself has all the properties I need but in this case one of the derived attributes also needs properties of its sub-entity, but that one is only returned as an id (b/c the first derived attribute did not care about it). I guess the same problem would pop up if my product/id-resolver was smarter and only fetched the attributes that it was asked for, instead of all of them.

caleb.macdonaldblack 2023-03-18T17:32:02.139439Z

I’ve read that response probably over 5 times so forgive me if I’ve misunderstood. I think you’re describing that a resolver might return X & Y attributes and a dependant resolver only needs X. But later on in the query another resolver needs Y. AFAIK, Pathom3 will know about all outputs (X & Y) of a single resolver, even if it’s not immediately needed.

Jakub Holý (HolyJak) 2023-03-18T17:46:16.001309Z

Ok, so the problem indeed is contained to situations where 2+ levels of subentities are involved, i.e. when we have to go over a nested reference? In my case I have order-line: • catalogue-number - needs production-method/num-id & more • label-count - needs product/labels-per-sheet & more • product ◦ product/labels-per-sheet ◦ product/production-method ▪︎ production-method/num-id and the problem is IMO with product/production-method being returned just as {production-method/id 345} , i.e. without any properties. If my catalogue-number resolver only depended on direct product attributes, it would be all fine.

caleb.macdonaldblack 2023-03-18T18:18:46.822709Z

So i have this and it all works. The num-id resolver being a simple alias should be pretty resilient. However if I change the product resolver output to this:

{:com.example.jakub2/product
                  [:com.example.jakub2.product/labels-per-sheet
                   :com.example.jakub2.product/production-method]}
Then the tests will fail with the error you described. If num-id has some nested nature to it, I would expect trouble

👀 1
Jakub Holý (HolyJak) 2023-03-18T18:35:16.495869Z

So what is the key thing here? That the product resolver declares not just :com.example.jakub2.product/production-method as its output but elaborates it to { :com.example.jakub2.product/production-method [:com.example.jakub2.product.production-method/id]} ?

caleb.macdonaldblack 2023-03-18T18:39:43.107459Z

Yeah, I’m trying to find out what could be causing your issue. That would definitely be doing it if you’re not describing your nesting in your output. If that’s not your issue then I’d be curious what your input and output look like for the num-id resolver

wilkerlucio 2023-03-18T18:47:56.836309Z

hello folks, I'm trying to understand the issue here, from what I gather the issue seems to be around situations where the same attribute is provided with different sub-queries, this is short example I can think:

(ns com.wsscode.pathom3.demos.nested-multiple
  (:require
    [com.wsscode.pathom3.connect.built-in.resolvers :as pbir]
    [com.wsscode.pathom3.connect.indexes :as pci]
    [com.wsscode.pathom3.connect.operation :as pco]
    [com.wsscode.pathom3.interface.eql :as p.eql]))

(pco/defresolver sub-a []
  {:thing {:a 1}})

(pco/defresolver sub-b []
  {:thing {:b 1}})

(def env
  (-> {}
      (pci/register
        [sub-a sub-b])))

(comment
  ; fine
  (p.eql/process env [{:thing [:a]}])

  ; fine
  (p.eql/process env [{:thing [:b]}])

  ; not fine, because Pathom would take 2 different paths for the same attribute
  (p.eql/process env [{:thing [:a :b]}]))

👀 1
wilkerlucio 2023-03-18T18:48:53.150109Z

is it the case?

caleb.macdonaldblack 2023-03-18T18:57:10.546959Z

Maybe. Not sure. @holyjak is able to exchange a single :production-method/id for his desired :production-method/num-id

Jakub Holý (HolyJak) 2023-03-18T18:57:33.240239Z

I have a repor here:

(ns com.tmp
  (:require
    [clojure.test :refer :all]
    [com.wsscode.pathom3.connect.indexes :as pci]
    [com.wsscode.pathom3.connect.operation :as pco]
    [com.wsscode.pathom3.interface.eql :as p.eql]))

(pco/defresolver catalogue-number
  [_env input]
  {::pco/input  [{:order/product [
                                  :product/production-method #_ ; TODO delete this line to see the test break
                                  {:product/production-method
                                   [:production-method/num-id]}]}]
   ::pco/output [:order/catalogue-number]}
  {:order/catalogue-number
   (->> input :order/product :product/production-method :production-method/num-id
        (str "catalogue-number-"))})
(pco/defresolver num-id
  [_env input]
  {::pco/input  [:production-method/id]
   ::pco/output [:production-method/num-id]}
  {:production-method/num-id
   (->> input
        (:production-method/id)
        (str "num-id-"))})
(pco/defresolver label-count
  [_env input]
  {::pco/input  [{:order/product [:product/labels-per-sheet]}]
   ::pco/output [:order/label-count]}
  {:order/label-count
   (-> input :order/product :product/labels-per-sheet)})
(pco/defresolver product-id
  [_env input]
  {::pco/input  [:product/id]
   ::pco/output [:product/id
                 :product/labels-per-sheet
                 :product/production-method]}
  {:product/id 222
   :product/labels-per-sheet 1337
   :product/production-method {:production-method/id "production-method-1"}})
(pco/defresolver order
  [_env input]
  {::pco/input  []
   ::pco/output [:order/id {:order/product [:product/id]}]}
  {:order/id 111
   :order/product {:product/id 222}})
;; TEST IT
(-> (pci/register [order product-id label-count num-id catalogue-number])
    (p.eql/process
      {}
      [:order/id
       :order/label-count
       :order/catalogue-number
       {:order/product [:product/labels-per-sheet
                        {:product/production-method [:production-method/num-id]}]}]))

Jakub Holý (HolyJak) 2023-03-18T18:57:42.079429Z

See the TODO line. With this line in, the call at the bottom succeeds. If I delete it and thus have the more elaborate input definition, it fails with > Pathom can’t find a path for the following elements in the query: [:production-method/num-id] …

caleb.macdonaldblack 2023-03-18T19:00:51.289389Z

(pco/defresolver product-id
  [_env input]
  {::pco/input  [:product/id]
   ::pco/output [:product/id
                 :product/labels-per-sheet
                 {:product/production-method
                  [:production-method/num-id]}]}
  {:product/id 222
   :product/labels-per-sheet 1337
   :product/production-method {:production-method/id "production-method-1"}})

caleb.macdonaldblack 2023-03-18T19:01:02.438299Z

That works.

caleb.macdonaldblack 2023-03-18T19:01:09.197429Z

Vs this which doesn’t

(pco/defresolver product-id
  [_env input]
  {::pco/input  [:product/id]
   ::pco/output [:product/id
                 :product/labels-per-sheet
                 :product/production-method]}
  {:product/id 222
   :product/labels-per-sheet 1337
   :product/production-method {:production-method/id "production-method-1"}})

Jakub Holý (HolyJak) 2023-03-18T19:03:36.802429Z

My bad, I should have ☝️ in my tests, as I do have it in my prod code…

caleb.macdonaldblack 2023-03-18T19:04:27.014529Z

With that fixed up, the example is working now.

Jakub Holý (HolyJak) 2023-03-18T19:04:44.889509Z

yes, so it must be another factor. Looking for it…

wilkerlucio 2023-03-18T19:05:42.583999Z

the output should always reflect the data, so product-id would be better as:

(pco/defresolver product-id
  [_env input]
  {::pco/input  [:product/id]
   ::pco/output [:product/id
                 :product/labels-per-sheet
                 {:product/production-method
                  [:production-method/id]}]}
  {:product/id 222
   :product/labels-per-sheet 1337
   :product/production-method {:production-method/id "production-method-1"}})

💯 1
wilkerlucio 2023-03-18T19:06:09.067229Z

and it does work in with this setup

caleb.macdonaldblack 2023-03-18T19:07:18.615059Z

Woops sorry my example had num-id returned. Should’ve been as wikerlucio had it

wilkerlucio 2023-03-18T19:07:33.915209Z

something that I did in the past was take notes of attributes that show up in the index as values (something opaque, like :product/id) vs as references (when the value has something declared inside of it), same value appearing as value and as reference is an indicator of a mistake

wilkerlucio 2023-03-18T19:09:23.297369Z

seems time to return it, rsrs, we can make an alert when registering an attribute in a differnet format from which the value is known to be (value vs ref)

Jakub Holý (HolyJak) 2023-03-18T19:21:14.759299Z

I am trying to make the test case closer to my production code but so far failing to replicate the problem

Jakub Holý (HolyJak) 2023-03-18T19:32:08.573319Z

So it seems to work just fine in the test case but not in production. The tricky part now is to finding the difference between the two that matters (likely a mistake in prod config)

caleb.macdonaldblack 2023-03-18T19:38:59.784429Z

There could be a resolver shadowing those ones.

Jakub Holý (HolyJak) 2023-03-18T22:00:47.727179Z

And the troublemaker is ….. ::pco/batch? true In the following resolver, if batch is true then I get the “insufficient input” error but if it is false then everything works out just fine:

(pco/defresolver fake-order-id
  [_env input]
  {::pco/input  [:order/id]
   ::pco/output [:order/yearly-sequence-number]
   ::pco/batch? false}
  (cond-> {:order/yearly-sequence-number 33}
          (sequential? input) vector))
(The input is sequential, so I end up returning the vector, when batch is true). It is way too late here now 😭 I will try to make a minimal repro case tomorrow.

caleb.macdonaldblack 2023-03-18T22:02:22.695029Z

Interesting. How do the attributes in that resolver relate to the ones from before?

Jakub Holý (HolyJak) 2023-03-19T18:58:13.967779Z

@caleb.macdonaldblack @wilkerlucio can you spot what is wrong here? It is not exactly the same problem as I have in prod (this one complains about catalogue-number, not product-method/*) but still it fails. Notice the two lines marked with TODO - changing either as suggested makes the query to succeed (ie. either batch to false or rm label-count from the query):

(ns com.tmp
  (:require
    [clojure.test :refer :all]
    [com.wsscode.pathom3.connect.indexes :as pci]
    [com.wsscode.pathom3.connect.operation :as pco]
    [com.wsscode.pathom3.interface.eql :as p.eql]))

(pco/defresolver derived-catalogue-number
  [_env {:keys [:order/yearly-sequence-number :order-line/product]}]
  {::pco/input [:order/yearly-sequence-number
                {:order-line/product [{:product/production-method [:production-method/num-id]}]}
                #_{:order-line/product [:product/production-method]}]
   ::pco/output [:order-line/catalogue-number]}
  {:order-line/catalogue-number
   (str "catalogue-number-seq" yearly-sequence-number "-numid"
        (-> product :product/production-method :production-method/num-id))})
(pco/defresolver derived-label-count
  [_env {:order-line/keys [product package-count]}]
  {::pco/input  [{:order-line/product [:product/labels-per-package]} :order-line/package-count]
   ::pco/output [:order-line/label-count]}
  {:order-line/label-count
   (* package-count (-> product :product/labels-per-package))})
(pco/defresolver fake-order-line-id
  [_env input]
  {::pco/input  [:order-line/id]
   ::pco/output [:order-line/id :order-line/package-count {:order-line/product [:product/id]}]
   ::pco/batch? true}
  (cond-> #:order-line{:id 111
                       :package-count 10
                       :product {:product/id #uuid "cf8b66fb-b963-433f-ab37-af3134061e49"}}
          (sequential? input) vector))
(pco/defresolver fake-order-id
  [_env input]
  {::pco/input  [:order/id]
   ::pco/output [:order/yearly-sequence-number]
   ::pco/batch? true} ; TODO Either set to false to remove label-count from the query to fix
  (cond-> {:order/yearly-sequence-number 33}
          (sequential? input) vector))
(pco/defresolver fake-product-id
  [_env input]
  {::pco/input [:product/id]
   ::pco/output [:product/labels-per-package {:product/production-method [:production-method/id]}]
   ::pco/batch? true}
  (cond-> {:product/labels-per-package 8
           :product/production-method {:production-method/id #uuid "a0269c9d-63a1-4e14-afa3-08f81ab0c002"}}
          (sequential? input) vector))
(pco/defresolver fake-production-method-id
  [_env input]
  {::pco/input  [:production-method/id]
   ::pco/output [:production-method/num-id]
   ::pco/batch? true}
  (cond-> {:production-method/num-id 3}
          (sequential? input) vector))
(pco/defresolver order-line->order
  [_env input]
  {::pco/input  [:order-line/id]
   ::pco/output [:order/id]}
  {:order/id #uuid"72e65f1b-088c-4817-82c9-622aa542ed06"})

(-> (pci/register [derived-catalogue-number derived-label-count fake-order-line-id fake-order-id order-line->order
                   fake-product-id fake-production-method-id])
    (p.eql/process
      {}
      [{[:order-line/id "fake-ol1"]
        [:order-line/id
         :order-line/label-count ; TODO Either remove this or fake-order-id's batch to fix
         :order-line/catalogue-number]}]))
Caleb, here you see how the fake-order-id related to the rest.

wilkerlucio 2023-03-20T00:03:24.792089Z

thanks for the report Jakub, I was able to repro and there is something strange about the batch not working there, but I need to dig deeper and understand better

🎉 1
wilkerlucio 2023-03-20T00:04:03.035059Z

in the meantime, I was playing with an idea want to check if you wanna try it. I was thinking about a way to make easier to generate repros, without having to keep doing those manual mocks

wilkerlucio 2023-03-20T00:04:13.111319Z

so I worked on this:

(defn capture-cache-key [env input]
  [input (pco/params env)])

(p.plugin/defplugin repro-capture
  {:com.wsscode.pathom3.connect.runner/wrap-root-run-graph!
   (fn [run-root]
     (fn [env ast-or-graph entity-tree*]
       (run-root env ast-or-graph entity-tree*)))

   :com.wsscode.pathom3.connect.runner/wrap-resolve
   (fn [resolve]
     (fn [{::keys [capture-context*] :as env} input]
       (let [op          (-> env ::pcp/node ::pco/op-name)
             capture-key (capture-cache-key env input)]
         (ctry
           (clet [response (resolve env input)]
             (swap! capture-context* assoc-in [::op-capture op capture-key] response)
             response)
           (catch Throwable e
             (swap! capture-context* assoc-in [::op-capture op capture-key]
                    {::throw {:msg (ex-message e) :data (ex-data e)}})
             (throw e))))))})

(defn mocked-op [{::keys [capture-context] :as env} input]
  (if-let [[_ response] (find (get-in capture-context [::op-capture (-> env ::pcp/node ::pco/op-name)]) (capture-cache-key env input))]
    response
    (throw (ex-info "Unexpected input to mocked call" {}))))

(defn mock-resolver [resolver]
  (-> resolver pco/operation-config
      (assoc ::pco/resolve mocked-op)))

(defn mock-mutation [mutation]
  (-> mutation pco/operation-config
      (assoc ::pco/mutate mocked-op)))

(defn extract-indexes [env]
  (-> env
      (select-keys [::pci/index-oir
                    ::pci/index-resolvers
                    ::pci/index-mutations])
      (update ::pci/index-resolvers update-vals pco/operation-config)
      (update ::pci/index-mutations update-vals pco/operation-config)))

(defn run-capturing [env entity request]
  (let [capture* (atom {})
        env'     (-> env
                     (assoc ::capture-context* capture*)
                     (p.plugin/register repro-capture))
        result   (try
                   (p.eql/process env' entity request)
                   (catch Throwable _ ::exception-result))]
    {::env     (-> (extract-indexes env')
                   (assoc ::capture-context @capture*))
     ::entity  entity
     ::request request
     ::result  result}))

(defn reproduce [{::keys [env entity request result]}]
  (let [env' (-> env
                 (coll/update-if ::pci/index-resolvers update-vals
                                 (comp pco/resolver #(assoc % ::pco/resolve mocked-op))))
        res  (p.eql/process env' entity request)]
    (if (= result res)
      res
      (throw (ex-info "Unexpected process result" {:expected result
                                                   :actual   res})))))

wilkerlucio 2023-03-20T00:04:33.249229Z

use case example:

;; use case

(pco/defresolver some-resolver []
  {:a 1})

(pco/defresolver b-resolver [{:keys [a]}]
  {:b (+ a 10)})

(pco/defresolver err []
  {:err (throw (ex-info "Err" {}))})

(pco/defresolver miss []
  {:miss ::pco/unknown-value})

(def env
  (-> {}
      (pci/register
        [some-resolver
         b-resolver
         err
         miss])))

(comment
  (-> (run-capturing env {:x [{:a 1} {:a 2} {:a 1} {:a 3}]} [{:x [:b]}])
      (reproduce))

  (-> (run-capturing env {} [:err])
      (reproduce))

wilkerlucio 2023-03-20T00:04:53.090719Z

if you can try this in your setup, I think this version is still naive, but I like to check if it works in a setup like yours