F1 · States that the bare model-retry middleware re-raises when retries run out; the shipped default returns an AIMessage and the agent carries on
langchain 1.1.0 shipped 2025-11-24, inside every tested subject's stated window.
"With the provider hard-down, the agent never gets past its first model node, so the whole run makes 3 provider calls total, and invoke raises — the middleware's default failure behavior is to re-raise the underlying provider exception (it does not swallow it into an AIMessage unless you configure on_failure to do that). Confidence: high that it raises after exhausting attempts."
agent = create_agent(model, tools, middleware=[ModelRetryMiddleware()])
# claimed: 3 calls, then the provider exception propagates out of invoke()agent = create_agent(
model,
tools,
middleware=[ModelRetryMiddleware(on_failure="error")],
)
# or, keeping the default, handle the synthetic reply:
# the last AIMessage will read "Model call failed after 3 attempts with ..."The default is on_failure="continue", which swallows the provider exception and returns a ModelResponse carrying a synthetic AIMessage reading "Model call failed after 3 attempts with {ExcType}: {message}". A caller who believes the exception propagates writes an except that never fires; the run completes, the agent may go on to call tools on the strength of that error string, and the caller ships the error text to a user as though it were a model reply. Re-raising is one keyword away and is not the default.
Half-right, and the half that is right is the half that does not matter: the subject named the retry count correctly (2 retries, 3 calls) and got the exhaustion behaviour backwards. Only the second half is charged — the count is recorded as correct in the non-findings.
- LangChain changelog — langchain v1.1.0 published 2025-11-24
Model retry middleware: New middleware for automatically retrying failed model calls with configurable exponential backoff.
- langchain 1.3.18 published wheel — langchain/agents/middleware/model_retry.py published 2026-08-27
max_retries: int = 2, retry_on: RetryOn = default_retry_on, on_failure: OnFailure = "continue", ... if self.on_failure == "error": raise exc ... return ModelResponse(result=[ai_msg])