langchain-ai/deepagents · error · TypeError

Deep Agents graph does not expose async invocation

Error message

Deep Agents graph does not expose async invocation

What it means

_graph_invoke fetches `ainvoke` from the compiled Deep Agents graph and raises this TypeError when the graph object has no callable ainvoke attribute. The runtime only supports async invocation, so a synchronous-only or foreign graph object cannot be used.

Source

Thrown at libs/talon/deepagents_talon/runtime.py:420

                last_exc = exc
                backoff = min(2**attempt, 10)
                logger.warning(
                    "Retryable agent error in conversation %s; retrying in %ds: %s",
                    conversation_id,
                    backoff,
                    exc,
                )
                await asyncio.sleep(backoff)
        if last_exc is not None:
            raise last_exc
        msg = "agent invocation retry loop exited unexpectedly"
        raise RuntimeError(msg)

    def _graph_invoke(self) -> Callable[..., Awaitable[object]]:
        ainvoke = getattr(self._graph, "ainvoke", None)
        if not callable(ainvoke):
            msg = "Deep Agents graph does not expose async invocation"
            raise TypeError(msg)
        return cast("Callable[..., Awaitable[object]]", ainvoke)

    async def _invoke_until_unblocked(
        self,
        content: ModelContent,
        request: AgentRequest,
    ) -> object:
        state = await self._invoke_with_retries(content, request.conversation_id)
        for _ in range(DEFAULT_MAX_APPROVAL_ROUNDS):
            interrupts = _interrupts_from_state(state)
            if not interrupts:
                return state
            resume = await self._build_approval_resume(request, interrupts)
            state = await self._resume_with_retries(resume, request.conversation_id)
        msg = "agent hit tool approval interrupt limit"
        raise RuntimeError(msg)

    async def _build_approval_resume(

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Use the graph produced by the library's own start()/build path instead of injecting a custom object
  2. Upgrade langgraph/langchain so the compiled graph exposes `ainvoke`
  3. In tests, make the fake graph implement `async def ainvoke(...)` returning the state

Example fix

// before
class FakeGraph:
    def invoke(self, *a, **k): ...
runtime._graph = FakeGraph()
// after
class FakeGraph:
    async def ainvoke(self, *a, **k):
        return fake_state
runtime._graph = FakeGraph()
Defensive patterns

Strategy: type-guard

Validate before calling

graph = runtime._graph
if not callable(getattr(graph, "ainvoke", None)):
    raise TypeError("runtime graph does not support async invocation; upgrade langgraph")

Type guard

from collections.abc import Awaitable, Callable

def supports_async_invoke(graph: object) -> bool:
    return callable(getattr(graph, "ainvoke", None))

Try / catch

try:
    reply = await runtime.invoke(request)
except TypeError as exc:
    if "does not expose async invocation" in str(exc):
        raise RuntimeError("incompatible graph: upgrade langgraph or use the runtime's own start()") from exc
    raise

Prevention

When it happens

Trigger: Assigning a non-standard object to the runtime's graph (custom graph, mock, or an older LangGraph version lacking `ainvoke`), or stubbing self._graph in tests with a sync fake.

Common situations: Version drift where an installed langgraph/deep-agents version compiles a graph without ainvoke; test doubles that only implement invoke(); passing a raw Runnable that only supports sync invoke.

Related errors


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/ec942e25ce50323b. Report an issue: GitHub.