pathom

smniel 2025-11-21T08:34:24.312819Z

Hi! I am getting the following error from pathom3:

Execution error (ExceptionInfo) at com.wsscode.pathom3.connect.runner/check-entity-requires! (runner.cljc:941).
Required attributes missing at path [:legacy-registration/custom-field-instances 0]:
- Attribute :legacy-custom-field-instance/rich-value was expected to be returned from resolver field-example/legacy-custom-field-instance-rich-value but inputs were missing:
  Can't find parent node that should provide attribute :legacy-custom-field-instance/custom-field, this is likely a bug in Pathom, please report it.
I have tried to replicate it in a trimmed down codebase and environment, but haven’t been able to. I would love to understand it and would be happy to help contribute a fix, but I haven’t gotten it figured out yet. Is there a way that you would most like this to be reported. I can happily dump my indexes, and the graphs that it is planning and executing as it goes, but I am unable to share the codebase. I would even be happy to pair sometime if that is a helpful thing in trying to understand exactly what is happening. Thanks in advance for any help!

wilkerlucio 2025-12-16T23:55:49.881739Z

hi @smniel, thanks for all the digging so far, and again sorry my delay. first, are you still having the issue? its being a long time already, but if so, have you tried unbatching the resolvers to see if the problem is related to batching?

smniel 2025-12-17T00:00:37.962969Z

I have been focusing on some other things, so I haven’t had to worry about it, but I will be back on it soonish, like in the next week or so.

smniel 2025-12-17T00:02:21.204539Z

I haven’t tried to unbatch it. The resolvers are dynamically generated to query a sql database, so it won’t be too straightforward, but I can try and make sometime to try it this week.

smniel 2025-12-17T00:03:56.111029Z

I feel pretty confident that the issue has to do with combination of returning nested attributes from inside of a batch, but I could not create a simple example to show this.

wilkerlucio 2025-12-17T00:04:34.675819Z

yeah, its a tricky place (nested + batching), which makes it super cool if we can unveil another edge case to be fixed on it

wilkerlucio 2025-11-28T13:17:49.403229Z

hi folks, I was on vacation, sorry the absense, will have a look in the thread later today

2025-11-21T13:30:15.080479Z

can you share what the query and any inputs look like? or at least the relevant parts of them.

smniel 2025-11-21T16:33:13.801069Z

Yeah, I would love to. This is the query query and the data, very simple, but the resolvers are not necessarily.

(p.eql/process
  indexes
  {:account/id ""}
  [{:account/field-instances
    [:field-instance/rich-value]}]))
The following resolvers are involved. I will put their inputs and output and whether they are batch resolvers.
account-field-instances
{::pco/input [:account/id]
 ::pco/output [{:account/field-instances
                [:field-instance/id
                 {:field-instance/field [:field/id]}]}]
 ::pco/batch? true}

field-instance-attributes
{::pco/input [:field-instance/id]
 ::pco/output [:field-instance/id
               :field-instance/created-at
               :field-instance/updated-at
               :field-instance/value
               {:field-instance/auto-id [:field-instance-auto-id/id]}
               {:field-instance/field [:field/id]}
               {:field-instance/form-instance [:form-instance/id]}]
 ::pco/batch? true}

field-instance-files
{::pco/input [:field-instance/id]
 ::pco/output [{:field-instance/files
                [:file/id
                 :file/created-at
                 :file/updated-at
                 :file/name
                 :file/mime-type
                 :file/key
                 :file/size
                 {:file/form-instance [:form-instance/id]}
                 {:file/field-instance [:field-instance/id]}]
 ::pco/batch?}



field-attributes
{::pco/input [:field/id]
 ::pco/output [:field/id
               :field/created-at
               :field/updated-at
               :field/deleted-at
               {:field/deleted-by [:user/id]}
               :field/label
               :field/alias-name
               :field/hint
               :field/icon
               :field/type
               :field/sort-order
               {:field/parent [:field/id]}
               :field/max-length
               :field/required
               :field/setting-auto-id]
 ::pco/batch? true}

field-instance-rich-value
{::pco/input [:field-instance/id
              :field-instance/value
              {:field-instance/auto-id
               [:field-instance-auto-id/id]}
              {:field-instance/files
               [:file/id
                :file/key
                :file/name
                :file/mime-type]}
              {:field-instance/field
               [:field/type
                :field/setting-auto-id]}]
 ::pco/output [:field-instance/rich-value]}

smniel 2025-11-21T16:36:11.310729Z

I can run the following query and it works as expected.

(p.eql/process
  indexes
  {:field-instance/id "<some-uuid>"}
  [:field-instance/rich-value])

smniel 2025-11-21T16:42:07.833039Z

But when I add the account layer like below it returns the error in the original message.

(p.eql/process
  indexes
  {:account/id ""}
  [{:account/field-instances
    [:field-instance/rich-value]}])
The strange part is that I can see that the field-attributes resolver does run and that the type and setting-auto-id attribute are returned, but it seems like they are merged after they are needed. I am not sure if this is because of the combination of batch processing and a nested-process or not. That is what I have been trying to trace.

2025-11-21T16:53:49.194549Z

what about if you do (p.eql/process indexes {:account/id "etc"} [{:account/field-instances [:field-instance/id]}])?

smniel 2025-11-21T16:54:53.549769Z

That works as expected.

2025-11-21T16:55:31.794329Z

okay. I'd try the same shape with each of the top-level inputs to field-instance-rich-value to make they're all reachable.

smniel 2025-11-21T16:56:46.728079Z

They are all reachable. I can run (p.eql/process indexes {:field-instance/id "etc"} [:field-instance/rich-value]) and it returns as expected.

2025-11-21T16:58:12.551159Z

sure, but I meant inside the [{:account/field-instances [...]}] box, since that's the part that's not working for the rich-value.

smniel 2025-11-21T16:58:44.221649Z

Gotcha. I can give that a try.

smniel 2025-11-21T17:01:07.262699Z

Yeah, that also works as expected.

2025-11-21T17:13:05.283269Z

what about selecting [{:account/field-instances [:field-instance/id :field-instance/rich-value]}]?

smniel 2025-11-21T17:13:21.335969Z

I edited part of the longer message, realizing that field-instance-files had all of the file attributes as output and the file-attributes resolver wasn’t being used.

smniel 2025-11-21T17:13:37.963579Z

Let me double check.

smniel 2025-11-21T17:14:50.449839Z

Same error as without the field instance id.

2025-11-21T17:14:55.107379Z

the next thing to check is copying the ::pco/input of field-instance-rich-value into that ... box [{:account/field-instances [...]}], ie. pulling all the inputs.

smniel 2025-11-21T17:16:17.017879Z

Yeah, I have done that and it fixes the problem. I didn’t even need to pull all of it in, just the two field attributes, type and setting-auto-id. I would prefer to figure out why pathom is unable to resolve it on it’s own though.

2025-11-21T17:16:56.440569Z

I agree, it was just a test to see if they worked together and there wasn't some lurking conflict.

2025-11-21T17:17:14.635289Z

I think I'm out of ideas, though 😞

smniel 2025-11-21T17:19:03.382629Z

So if I change the output of account-field-instances to the following it works:

[{:account/field-instances
  [:field-instance/id
   {:field-instance/field
    [:field/id
     :field/type
     :field/setting-auto-id]}]}]

smniel 2025-11-21T17:19:40.276499Z

I appreciate you looking at it.

2025-11-21T17:20:15.194719Z

oh, that might make sense.

2025-11-21T17:21:47.242719Z

wait, no, that shouldn't be necessary. Pathom should for sure be able to resolve that with the other resolver.

smniel 2025-11-21T17:22:25.552169Z

Yeah, it even does for many queries.

2025-11-21T17:23:58.796699Z

usually when I've had trouble like this, it's because I was mixing inputs from different scopes on the same resolver. like if you had :account/id, :field-instance/id and :field/id as siblings in a ::pco/input. it doesn't really make sense - they're properties of different entities and you need to show their relationships using EQL joins (maps).

smniel 2025-11-21T17:28:09.611929Z

We don’t currently have any “mixed” entities with our resolvers. I have considered it, but given that you can only do that for one to one relationships, I didn’t like the inconsistency.

2025-11-21T17:29:58.723349Z

it's actually even stronger than that - it only works for unique 1-1 relationships. if the same key is used for two different relationships then they collide. definitely better to be explicit and use the joins, unless it's really more like "this is one entity semantically but it's stored as two"

smniel 2025-11-21T17:30:27.934169Z

We also have instances where we have multiple one to one relationships from one entity to an entity of the same type. It seemed that it could get very confusing doing that.

smniel 2025-11-21T20:23:40.480159Z

I found the beginning of something helpful with a bunch of logging. I am logging the beginning of each pcr/run-graph-impl! using the wrap-run-graph! plugin. I went a put some other logging that wraps each run of a resolver, as well as each run of a batch. The full logs are here. https://gist.github.com/scizo/b1f68dd621a7a250e25ce1f7f69009bd It doesn’t seem to be a problem with the planner. It is correctly calling the needed resolver, but it happens in a batch. Later when the same node is run again to merge the result that was cached with the batch (at least I think that is how it might be working). The node result is nil. The interesting logs start on line 370 when the batch with the needed resolver gets run. The node is then rerun on line 400, but the entity already has all of the expected data. I am wondering if that is why the result comes back as nil. The nil result is probably a red herring. I am still combing through this trying to see if it can give me some hints about where to go next.

smniel 2025-11-21T20:32:31.918269Z

Then on line 427, the root node of the middle graph begins to run and it doesn’t have the data from the graph below merged in, even though it has run and been merged into the sub-graph entity.

smniel 2025-11-21T20:49:50.640869Z

I thinking because one batch is created before the other is run, the inputs are captured before some of the needed inputs are merged.

smniel 2025-11-21T23:00:22.768699Z

@wilkerlucio Any thoughts on this?