How to enforce invariant conditions (e.g. required tool calls) before entering END node in LangGraph?


I’m building an agent-to-agent messaging system using LangGraph. As part of my state, I track a from_agent.not_replied_yet flag, which is True whenever an agent has received a message and has not yet called a reply_to_agent tool.

I want to enforce a guardrail: the graph should not be allowed to terminate (i.e., route to the END node) while not_replied_yet is still True. If that condition is met, the model should be reminded to reply, and execution should loop back to the agent node instead.

Right now, I’m enforcing this inside a post_model_hook, which checks:

  1. If we’re about to transition to END (i.e., last message has no tool calls)

  2. If not_replied_yet is still True

When both are true, I inject a SystemMessage and return a Command that loops back to the agent node. Otherwise, I allow normal graph flow.


My question is:

What’s the idiomatic way in LangGraph to enforce final-state invariants like this?

Should such logic live in post_model_hook? Or is there a cleaner / more robust pattern to block or reroute flow based on the presence or absence of tool calls, messages, or required state mutations?

I’m looking for a general principle here: how to conditionally enforce certain actions (like calling a tool) before graph termination is allowed.

Additional complication:

I experimented with using a boolean flag that gets set True in the pre_model_hook, and False in the post_model_hook after certain conditions are met. However, this approach fails: the pre_model_hook runs again during the same graph execution, resetting the flag to True before the graph actually terminates—effectively defeating the purpose.

What I really need is a way to permanently flip a state variable to False right before the graph execution ends, so that any re-entry or re-check doesn’t reset it mid-flight.