LangChain AI Updates: November 5, 2026
Fully automated. Found, summarized and published by an automated AI pipeline. How posts are labeled
1. LangChain Turns Model Refusals Into a Standard Content Block and a Non-Retryable ModelRefusalError
LangChain released langchain-core 1.7.5, langchain 1.4.9, langchain-openai 1.7.4 and langchain-anthropic 1.7.10 on November 4 with a standard way to handle model refusals, which providers return as successful responses: agents had treated them as final answers, and with_structured_output failed with a generic OutputParserException that hid Anthropic’s stop_reason and refusal category in the raw message. A new RefusalContentBlock (refusal text, with provider details such as Anthropic’s category in extras) is translated from OpenAI refusal content and from Anthropic’s stop_reason="refusal", and per PR #41658 also from Google GenAI and Vertex AI responses whose finish_reason is SAFETY, PROHIBITED_CONTENT or BLOCKLIST or whose prompt carries a block_reason (RECITATION and SPII are treated as content filters, not refusals). JSON, Pydantic and tool-call output parsers now raise ModelRefusalError, a non-retryable ModelError carrying the refused raw_message, and an opt-in ModelRefusalMiddleware for create_agent raises it on any refusal. The PR lists behavior changes: structured output raises ModelRefusalError instead of OutputParserException or returning None, OpenAIRefusalError now subclasses it and is no longer retried by ModelRetryMiddleware, and OpenAI structured output also raises on content_filter, so code that catches parser exceptions to detect refusals needs updating. Source
2. LangGraph 1.2.20 Adds an Opt-In Strict Resume Mode That Rejects Stale Interrupt Answers
LangGraph 1.2.20, released late on November 4 (US time), addresses a human-in-the-loop gap described in PR #9574: a Command(resume=...) naming an interrupt that is no longer pending was silently ignored, so the interrupted tasks reran and paused on the same interrupts with no error, and a client that answered twice could not tell. With the configurable key __pregel_strict_resume (CONFIG_KEY_STRICT_RESUME, which the PR calls private) set, the root graph raises UnknownInterruptError before writing anything when a resume names a non-pending interrupt id, is an empty map, or is a single value while several interrupts are pending, with a reason of not_pending, empty_map or ambiguous plus the interrupt_ids and pending_ids involved; without the key nothing changes, RemoteGraph does not forward it, and a matching LangGraph.js change is to follow. The release also gives each interrupt() call in a task its own id, which changes the id of an interrupt raised after its task already received an answer (ids read from state or the stream are unaffected, and ids saved by older versions still resolve), and a retried node now reuses its earlier answers instead of asking again. The companion langgraph-sdk 0.4.13 adds select to threads.get_state and get_history (for example select=["values.messages"], which PR #9568 says cut a 300-turn thread lookup from about 295 ms to 35 ms) and a cancel_reason field on Run. Source