Deep Agents: Custom state fields not accessible in ToolRuntime.state

@xuro-langchain Thanks a lot for your reply — that really helped!
Later I realized your suggestion was already in the documentation (my bad :sweat_smile:): Middleware - Docs by LangChain

Now I’m running into a related issue: INVALID_CONCURRENT_GRAPH_UPDATE - Docs by LangChain
I have a hypothesis that since all my SubAgents share the same CustomMiddleware and CustomState (AgentState) schema — even for values that don’t change — there might be some concurrency when the subgraphs “return” and try to rewrite the same values in the shared ‘main graph’ state.

Here’s an example of the error I’m seeing:

InvalidUpdateError("At key 'load_id': Can receive only one value per step. Use an Annotated key to handle multiple values.\nFor troubleshooting, visit: https://docs.langchain.com/oss/python/langgraph/errors/INVALID_CONCURRENT_GRAPH_UPDATE")Traceback (most recent call last):


  File "/usr/local/lib/python3.12/site-packages/langgraph/pregel/main.py", line 2689, in stream
    loop.after_tick()


  File "/usr/local/lib/python3.12/site-packages/langgraph/pregel/_loop.py", line 545, in after_tick
    self.updated_channels = apply_writes(
                            ^^^^^^^^^^^^^


  File "/usr/local/lib/python3.12/site-packages/langgraph/pregel/_algo.py", line 294, in apply_writes
    if channels[chan].update(vals) and next_version is not None:
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^


  File "/usr/local/lib/python3.12/site-packages/langgraph/channels/last_value.py", line 64, in update
    raise InvalidUpdateError(msg)


langgraph.errors.InvalidUpdateError: At key 'load_id': Can receive only one value per step. Use an Annotated key to handle multiple values.
For troubleshooting, visit: https://docs.langchain.com/oss/python/langgraph/errors/INVALID_CONCURRENT_GRAPH_UPDATE

Note: The load_id attribute (from my custom state) never changes.

Does that theory make sense?

If so:

  1. Is the recommended fix (as mentioned in the docs) to create a reducer, maybe to safely replace or merge the state values?

  2. In this case, order isn’t really an issue because the value doesn’t change — but for other state fields it might be. What are the best practices around handling this kind of concurrency in shared state?