One section per release, oldest first. Start below the version you have and read down to the one you are moving to. Each section lists what breaks, the compiler errors it raises and what Emendant patches.
- 1.0.3: getContextVariable and setContextVariable removed 4 breaking, 0 deprecations
- 1.0.5: piiRedactionMiddleware deprecated 5 breaking, 2 deprecations
- 1.1.0: ConfigurableModel._model renamed, systemPrompt takes a SystemMessage 3 breaking, 0 deprecations
- 1.2.7: ReactAgent takes one AgentTypeConfig instead of four type parameters 2 breaking, 0 deprecations
- 1.2.12: MiddlewareError.isInstance becomes static, and the constructor private 1 breaking, 0 deprecations
- 1.2.13: ToolCallRequest.tool can be undefined, and agents take LangGraph state schemas 2 breaking, 0 deprecations
- 1.2.24: ReactAgent.stream gains a TSubgraphs type parameter 1 breaking, 0 deprecations
- 1.2.29: ConfigurableModel.withStructuredOutput accepts a Standard Schema 1 breaking, 0 deprecations
- 1.2.35: ReactAgent.getSubgraphAsync renamed to getSubgraphsAsync 1 breaking, 0 deprecations
- 1.2.36: ConfigurableModel requires getLsParamsWithDefaults and retypes withStructuredOutput 1 breaking, 0 deprecations
- 1.2.39: agents accept any runnable model, typed as AgentLanguageModelLike 4 breaking, 0 deprecations
- 1.4.0: streamEvents v3 for agents, and AgentTypeConfig requires StreamTransformers 6 breaking, 0 deprecations
- 1.4.1: @langchain/core 1.1.47 deprecates streamEvents v1 on tools and fake models 5 breaking, 0 deprecations
- 1.4.4: MiddlewareTypeConfig requires StreamTransformers 8 breaking, 0 deprecations
- 1.4.6: streamEvents without a version, and a when predicate for human review 5 breaking, 0 deprecations
- 1.5.3: MiddlewareError's ~brand moves onto the instance 2 breaking, 0 deprecations
- 1.5.16: piiRedactionMiddleware and PIIRedactionMiddlewareConfig deprecated 0 breaking, 4 deprecations
- 1.5.17: InterruptOnConfig and HumanInTheLoopMiddlewareConfig members changed 4 breaking, 0 deprecations
langchain 1.0.3 for JavaScript: getContextVariable and setContextVariable removed
langchain@1.0.3 stops exporting getContextVariable and setContextVariable from the package root. Both functions are defined in @langchain/core/context, and langchain re-exported them through 1.0.2; the import that did so is gone from the published 1.0.3 build, and none of the release’s six changelog entries names either function. Any import of the two names from langchain now fails to resolve.
What changed
- Two named exports removed, and the changelog does not say so.
getContextVariableandsetContextVariableare gone from thelangchainpackage root in 1.0.3. Comparing the publisheddist/index.d.tsfiles for 1.0.2 and 1.0.3 shows the re-exporting import dropped between the two; the six patch entries inlangchain’sCHANGELOG.mdfor 1.0.3 mention neither name. - The functions did not move out of the ecosystem. Both are still defined and exported from
@langchain/core/context, which is wherelangchainread them from in the first place.langchainre-exported them rather than owning them, and only the re-export went away. - Two middleware options widen.
SummarizationMiddlewareConfig.modelaccepts a model string as well as aBaseLanguageModel, which the changelog lists as “allow for model strings in summarization middleware.”ToolCallLimitConfig.exitBehaviorgains"continue"beside"end"and"error", and 1.0.3 documents it as the default: exceeded tools are blocked with error messages while other tools continue. Code that reads either option back and treats it as the old type, a model object or one of two behaviours, is what these two findings are about.
Before and after
A program that imported both from the package root:
import { getContextVariable, setContextVariable } from 'langchain';Both changes carry an assisted fix, so emendant fix writes this rewrite once you name a model provider. The working replacement, confirmed against the published @langchain/core@1.0.3 package, is to import from the subpath that still carries them:
import { getContextVariable, setContextVariable } from '@langchain/core/context';Migration guidance and its limits
The two import findings carry an assisted fix. Name a model provider on the command line or in emendant.json and emendant fix writes the specifier change; without one they are reported with their guidance and nothing is sent anywhere. Review the assisted patch before applying it. It is checked, in a copy of your repository moved to 1.0.3 and put through whichever of your own typecheck and tests it finds there.
Import getContextVariable and setContextVariable from @langchain/core/context in place of langchain. That subpath’s exports are unchanged between @langchain/core 1.0.2 and 1.0.3, so nothing else about the call sites needs to change.
The two middleware findings are medium confidence and also assisted. Review whether the changed members affect your code before applying a patch. Where code reads model from a summarization config, handle the string case; where it reads exitBehavior, add "continue". If you relied on the tool call limit’s default, check that blocking and continuing is what you want.
The scan detects named imports of getContextVariable or setContextVariable from langchain, and nothing else. A namespace import, a re-export of either name through a module of your own, or a dynamic import('langchain') is not covered, so a clean scan does not prove the two names are gone from your code, only that no direct named import of them from langchain remains.
The removal is absent from langchain’s own changelog for 1.0.3, so there is no migration note from the maintainers to check this page against beyond the published package itself. Treat the six listed patch changes in that release as unrelated to this page.
What Emendant detects, fixes and verifies
4 changes in langchain 1.0.3. 0 automatic fixes, 4 fixes requiring a model provider you choose, 0 report only. Each patch states which checks passed. Understand patch evidence.
| Change | Severity | Detects | Fix | Verified by |
|---|---|---|---|---|
Removed getContextVariablelangchain-npm-1.0.3-get-context-variable-removed | Breaking |
| Patch, only when you name a model provider | Your typecheck and tests |
Removed setContextVariablelangchain-npm-1.0.3-set-context-variable-removed | Breaking |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of SummarizationMiddlewareConfiglangchain-npm-1.0.3-summarization-middleware-config-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of ToolCallLimitConfiglangchain-npm-1.0.3-tool-call-limit-config-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
emendant explain <change-id> prints any row's entry, guidance and sources at the terminal.
The error TS lines are what TypeScript 5.9.3 printed when code that compiled against langchain 1.0.2 was compiled against 1.0.3. A row without one is a change the compiler does not report, such as a deprecation or a change in behaviour.
Requires emendant@0.3.0 or later. Feed entry feed/npm/langchain/1.0.3.json, snapshot 2026-09-23.4.
Primary sources
langchain 1.0.5 for JavaScript: piiRedactionMiddleware deprecated
langchain@1.0.5 marks its PII redaction middleware deprecated and ships a replacement for it in the same release. In the published declaration files, piiRedactionMiddleware and its options type PIIRedactionMiddlewareConfig both carry a bare @deprecated marker, where 1.0.4 declared the function @public and gave the type no marker at all. Both names are still exported from the package root and both still work, so an upgrade from 1.0.4 compiles; none of the five patch entries in the release’s changelog mentions either name.
What changed
- Both PII redaction exports are deprecated, and the marker names no successor.
@deprecatedappears on its own indist/agents/middleware/piiRedaction.d.tsfor the function and for the type, with no replacement in the tag and no removal date. Emendant reports each named import of either one fromlangchain, which is how you find the call sites before a later major removes them. - The replacement arrived in the same release, with a different shape. 1.0.5 adds
piiMiddlewareand a newagents/middleware/piimodule behind it, along withPIIMiddlewareConfig,PIIStrategy,BuiltInPIITypeand five detectors. It takes one PII type per call rather than a record of rules, so porting is not a rename. - Context editing now follows the summarization interface. The changelog says so in those words. On
ClearToolUsesEditConfig,keepwas a number and is now{ messages?, tokens?, fraction? }, and a newtriggertakes the same condition shape;triggerTokens,keepMessagesandclearAtLeastare kept but marked@deprecated. AContextEditof your own must change itsapply: it used to receive{ tokens, messages, countTokens }and return a number, and now receives{ messages, countTokens, model? }and returns nothing.ClearToolUsesEdititself carriesmodelandtriggerand no longertriggerTokens. exitBehavior: "throw"is now"error". OnModelCallLimitMiddlewareConfigthe values are"end"and"error", and"throw"no longer type checks. The changelog lists “rename exit behavior from throw to error.”ReactAgent’s streams are typed.streamandstreamEventsnow type their output by stream mode, where 1.0.4 returnedanychunks.
Before and after
The deprecated middleware took a record of custom regular expressions in a single call, as its own declaration example shows:
import { createAgent, piiRedactionMiddleware } from 'langchain';
const agent = createAgent({ model: new ChatOpenAI({ model: 'gpt-4' }), tools: [lookupUser], middleware: [piiRedactionMiddleware({ rules: { ssn: /\b\d{3}-?\d{2}-?\d{4}\b/g } })],});Moving to piiMiddleware changes the configuration and how redacted values are handled. The following example comes from the new declaration. Review the behaviour your application needs before porting each call:
import { createAgent, piiMiddleware } from 'langchain';
const agent = createAgent({ model: 'openai:gpt-4', middleware: [piiMiddleware('email', { strategy: 'redact' })],});Migration guidance and its limits
Emendant identifies the deprecated imports and supports assisted fixes when you name a model provider. Both names still work in this release. Moving to piiMiddleware needs a deliberate migration because its configuration and behaviour differ; an automatic patch may not be available for these sites.
Port each call site deliberately. piiRedactionMiddleware accepted any number of custom rules as named regular expressions, and its documentation says it restored the original values into model responses so tools received them unredacted. piiMiddleware takes one type per call, from email, credit_card, ip, mac_address and url or a custom type with a detector, and offers block, redact, mask and hash as strategies. The new declaration describes no restore step, so a tool that needs the real value needs rethinking rather than a new argument.
The five other findings are medium confidence and assisted too. Review whether the changed members affect your code before applying a patch. Two need a hand wherever they appear: write keep as { messages: n } where it was n, and replace exitBehavior: "throw" with "error". A custom ContextEdit needs its apply rewritten to the new parameters; the ClearToolUsesEdit declaration is the model to follow. Code that read ReactAgent stream chunks as any may now need to narrow them.
Check the scope defaults while you are there. applyToInput defaults to true, and applyToOutput and applyToToolResults both default to false, so a single piiMiddleware call covers less of the conversation than the old middleware’s two phases did.
The scan detects named imports of the two deprecated exports from langchain, including local aliases. An import of BuiltInPIIType renamed to piiRedactionMiddleware on the way in is not a use of the deprecated function and is not reported, and neither is either name imported from a compatibility module of your own. The package exposes no subpath for this middleware, so the root import is the only route Emendant has to cover, but a namespace import, a re-export through your own module or a dynamic import('langchain') is still outside what these two entries see. A clean scan does not prove your agents have left the deprecated middleware behind.
What Emendant detects, fixes and verifies
7 changes in langchain 1.0.5. 0 automatic fixes, 7 fixes requiring a model provider you choose, 0 report only. Each patch states which checks passed. Understand patch evidence.
| Change | Severity | Detects | Fix | Verified by |
|---|---|---|---|---|
Deprecated PIIRedactionMiddlewareConfiglangchain-npm-1.0.5-piiredaction-middleware-config-deprecated | Deprecation |
| Patch, only when you name a model provider | Your typecheck and tests |
Deprecated piiRedactionMiddlewarelangchain-npm-1.0.5-pii-redaction-middleware-deprecated | Deprecation |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of ClearToolUsesEditlangchain-npm-1.0.5-clear-tool-uses-edit-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of ClearToolUsesEditConfiglangchain-npm-1.0.5-clear-tool-uses-edit-config-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of ContextEditlangchain-npm-1.0.5-context-edit-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of ModelCallLimitMiddlewareConfiglangchain-npm-1.0.5-model-call-limit-middleware-config-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of ReactAgentlangchain-npm-1.0.5-react-agent-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
emendant explain <change-id> prints any row's entry, guidance and sources at the terminal.
Requires emendant@0.3.0 or later. Feed entry feed/npm/langchain/1.0.5.json, snapshot 2026-09-23.5.
Primary sources
LangChain.js 1.1.0: ConfigurableModel._model renamed, systemPrompt takes a SystemMessage
langchain@1.1.0 adds model retry and OpenAI moderation middleware, lets an agent’s systemPrompt be a SystemMessage, and caches model instance imports in initChatModel. Three types change with it. The one that stops compiling is a call to _model() on the ConfigurableModel that initChatModel returns, which is now _getModelInstance(). The other two widen, and break only code that reads them back.
What changed
ConfigurableModel._modelis now_getModelInstance. The method that resolves the underlying chat model keeps its signature,(config?: RunnableConfig) => Promise<BaseChatModel<...>>, under the new name. The class also gains a private instance cache.systemPromptmay be aSystemMessage. OnCreateAgentParamsit wasstringand is nowstring | SystemMessage. The changelog lists it as “SupportSystemMessageassystemPrompt.” Code that reads it and treats it as a string must narrow it.onFailuregains"error"and"continue". OnToolRetryMiddlewareConfig,"continue"is the new default, returning anAIMessagewith the error details, and"error"re-raises. The declaration documents"raise"as “use"error"instead” and"return_message"as “use"continue"instead”; both are still accepted.
Before and after
The affected type is imported from this module:
import type { ConfigurableModel } from 'langchain/chat_models/universal';The method as langchain@1.0.6 declared it, with the type arguments shortened:
_model(config?: RunnableConfig): Promise<BaseChatModel<...>>;And as 1.1.0 declares it:
_getModelInstance(config?: RunnableConfig): Promise<BaseChatModel<...>>;Migration guidance and its limits
All three findings carry an assisted fix at medium confidence. Name a model provider on the command line or in emendant.json and emendant fix tries them; without one they are reported with their guidance and nothing is sent anywhere. Review whether the changed members affect your code before applying a patch. Sites that only construct these values may need no edit. Emendant checks each patch in a copy of your repository at 1.1.0 and withholds patches that fail. Read the patch header to see which checks passed.
Rename calls to _model(...) on a ConfigurableModel to _getModelInstance(...); the method is underscored and outside the documented API, so check whether you still need it. Where code reads systemPrompt from agent params, handle the SystemMessage case. Move onFailure: "raise" to "error" and "return_message" to "continue"; the old values are not reported by these entries.
ConfigurableModel is matched when it is imported from langchain/chat_models/universal, and the other two from langchain. A model returned by initChatModel and used with its type inferred is not a finding, although the compiler will name a _model call on it. A clean scan says no file names these three types from those modules, and nothing more about the release.
What Emendant detects, fixes and verifies
3 changes in langchain 1.1.0. 0 automatic fixes, 3 fixes requiring a model provider you choose, 0 report only. Each patch states which checks passed. Understand patch evidence.
| Change | Severity | Detects | Fix | Verified by |
|---|---|---|---|---|
Changed the members of CreateAgentParamslangchain-npm-1.1.0-create-agent-params-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of ToolRetryMiddlewareConfiglangchain-npm-1.1.0-tool-retry-middleware-config-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of ConfigurableModellangchain-npm-1.1.0-chat-models-universal-configurable-model-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
emendant explain <change-id> prints any row's entry, guidance and sources at the terminal.
Requires emendant@0.3.0 or later. Feed entry feed/npm/langchain/1.1.0.json, snapshot 2026-09-23.4.
Primary sources
LangChain.js 1.2.7: ReactAgent takes one AgentTypeConfig instead of four type parameters
langchain@1.2.7 refactors the agent generics into type bags. ReactAgent used to take four type parameters, for the structured response, the state schema, the context schema and the middleware. It now takes one, Types extends AgentTypeConfig, that carries all of them and the tools. Code that writes ReactAgent<...> with type arguments stops compiling. Code that lets createAgent infer the agent’s type does not change.
What changed
ReactAgenttakes one type argument.ReactAgent<StructuredResponseFormat, StateSchema, ContextSchema, TMiddleware>is nowReactAgent<Types extends AgentTypeConfig>.AgentTypeConfighas the membersResponse,State,Context,MiddlewareandTools. The class also declares a required"~agentTypes"member that holds the bag, and the types ofinvoke,stream,streamEvents,graph,builderandoptionsare written in terms of it.AgentMiddlewaregains aTToolsparameter. It is the fourth type parameter and has a default, so existing references compile. The interface declares an optional"~middlewareTypes"of typeMiddlewareTypeConfig, and its hooks and schemas are typed through it.- Helpers read the bags.
InferAgentResponse,InferAgentStateand related helper types take an agent and return one part of its config. The changelog lists the refactor as a fix.
Before and after
The affected type is imported from this module:
import type { ReactAgent } from 'langchain';The class head as langchain@1.2.6 declared it:
declare class ReactAgent<StructuredResponseFormat extends Record<string, any> | ResponseFormatUndefined = Record<string, any>, StateSchema extends AnyAnnotationRoot | InteropZodObject | undefined = undefined, ContextSchema extends AnyAnnotationRoot | InteropZodObject = AnyAnnotationRoot, TMiddleware extends readonly AgentMiddleware[] = readonly AgentMiddleware[]> {And as 1.2.7 declares it:
declare class ReactAgent<Types extends AgentTypeConfig = AgentTypeConfig<Record<string, any>, undefined, AnyAnnotationRoot, readonly AgentMiddleware[], readonly (ClientTool | ServerTool)[]>> {Migration guidance and its limits
Both findings carry an assisted fix at medium confidence. Name a model provider on the command line or in emendant.json and emendant fix tries them. Without one, they are reported with their guidance and nothing is sent anywhere. Review whether the changed members affect your code before applying a patch. A bare ReactAgent or AgentMiddleware with no type arguments still compiles, and those sites may need no edit. Emendant checks each patch in a copy of your repository at 1.2.7 and withholds patches that fail. Read the patch header to see which checks passed.
Rewrite ReactAgent<R, S, C, M> as ReactAgent<AgentTypeConfig<R, S, C, M>>, adding the tools as a fifth argument where they matter. Where a function takes an agent, typing the parameter as typeof agent and reading parts with the helper types avoids restating the config.
The scan reports the two names in a type position when they are imported from langchain. A createAgent call whose result is inferred is not a finding, and it needs no change. A clean scan says no file names ReactAgent or AgentMiddleware from langchain, and nothing more about the release.
What Emendant detects, fixes and verifies
2 changes in langchain 1.2.7. 0 automatic fixes, 2 fixes requiring a model provider you choose, 0 report only. Each patch states which checks passed. Understand patch evidence.
| Change | Severity | Detects | Fix | Verified by |
|---|---|---|---|---|
Changed the members of AgentMiddlewarelangchain-npm-1.2.7-agent-middleware-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of ReactAgentlangchain-npm-1.2.7-react-agent-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
emendant explain <change-id> prints any row's entry, guidance and sources at the terminal.
Requires emendant@0.3.0 or later. Feed entry feed/npm/langchain/1.2.7.json, snapshot 2026-09-23.5.
Primary sources
LangChain.js 1.2.12: MiddlewareError.isInstance becomes static, and the constructor private
langchain@1.2.12 changes how a MiddlewareError is made and recognised, so that graph interrupts raised inside middleware propagate unchanged instead of being wrapped. isInstance moves from the instance to the class, and the constructor becomes private, with a static wrap in its place. Code that calls err.isInstance(...) on an error, or constructs a MiddlewareError itself, stops compiling.
What changed
isInstanceis static. In 1.2.11 it was declared on the instance, asisInstance(error: unknown): error is MiddlewareError. In 1.2.12 it isstatic isInstance(...)with the same signature, so the call isMiddlewareError.isInstance(error).- The constructor is private, and
wrapreplaces it.static wrap(error: unknown, middlewareName: string): Errorreturns the original error when it is a graph bubble-up error such asGraphInterrupt, and a newMiddlewareErrorotherwise. The changelog lists the release as “bubble up graph interrupt errors as is.” This part has no row of its own; the entry detects the type and names onlyisInstance.
Before and after
The affected type is imported from this module:
import type { MiddlewareError } from 'langchain';The class as langchain@1.2.11 declared it:
declare class MiddlewareError extends Error { static readonly "~brand" = "MiddlewareError"; constructor(error: unknown, middlewareName: string); isInstance(error: unknown): error is MiddlewareError;}And as 1.2.12 declares it, with the doc comments removed:
declare class MiddlewareError extends Error { static readonly "~brand" = "MiddlewareError"; private constructor(); static wrap(error: unknown, middlewareName: string): Error; static isInstance(error: unknown): error is MiddlewareError;}Migration guidance and its limits
The finding carries an assisted fix at medium confidence. Name a model provider on the command line or in emendant.json and emendant fix tries it; without one it is reported with its guidance and nothing is sent anywhere. Review whether the changed members affect your code before applying a patch. A site that only names the type in a catch narrowing or a signature may need no edit. Emendant checks each patch in a copy of your repository at 1.2.12 and withholds patches that fail. Read the patch header to see which checks passed.
Replace someError.isInstance(x) with MiddlewareError.isInstance(x). Replace new MiddlewareError(error, name) with MiddlewareError.wrap(error, name), and note that its return type is Error: when the wrapped error is a graph interrupt you get the interrupt back, which is the point of the change, so code that assumed it always held a MiddlewareError needs a check.
The scan reports MiddlewareError in a type position when it is imported from langchain. A new MiddlewareError(...) or an isInstance call on an error whose type is inferred is not a finding by itself, although the compiler will name both. A clean scan says no file names MiddlewareError from langchain, and nothing more about the release.
What Emendant detects, fixes and verifies
1 change in langchain 1.2.12. 0 automatic fixes, 1 fixes requiring a model provider you choose, 0 report only. Each patch states which checks passed. Understand patch evidence.
| Change | Severity | Detects | Fix | Verified by |
|---|---|---|---|---|
Changed the members of MiddlewareErrorlangchain-npm-1.2.12-middleware-error-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
emendant explain <change-id> prints any row's entry, guidance and sources at the terminal.
Requires emendant@0.3.0 or later. Feed entry feed/npm/langchain/1.2.12.json, snapshot 2026-09-23.4.
Primary sources
LangChain.js 1.2.13: ToolCallRequest.tool can be undefined, and agents take LangGraph state schemas
langchain@1.2.13 adds dynamic tool registration through middleware and state schema support for agents. Both change types middleware authors use. In wrapToolCall, request.tool is now undefined for a tool the agent was not created with, so code that reads it unguarded stops compiling. And an agent’s state schema may now be a LangGraph StateSchema as well as a Zod object.
What changed
ToolCallRequest.toolmay beundefined. It wasClientTool | ServerTooland is nowClientTool | ServerTool | undefined. Its documentation says it isundefinedfor dynamically registered tools, and that middleware should then supply the implementation by spreading the request with atool.- State schemas are no longer Zod only.
DefaultMiddlewareTypeConfig.Schemachanges fromInteropZodObject | undefinedtoStateDefinitionInit | undefined. The changelog describes the move to LangGraph’s nativeStateSchema,ReducedValueandUntrackedValueprimitives, with Zod v3 and v4 objects still accepted as input, and a newcreateAgentStatereplacingcreateAgentAnnotationConditional.
Before and after
The affected type is imported from this module:
import type { ToolCallRequest } from 'langchain';The member as langchain@1.2.12 declared it:
tool: ClientTool | ServerTool;And as 1.2.13 declares it:
tool: ClientTool | ServerTool | undefined;The handling the release documents for it:
wrapToolCall: async (request, handler) => { if (request.toolCall.name === "dynamic_tool" && !request.tool) { // Provide the tool implementation for dynamically registered tools return handler({ ...request, tool: myDynamicTool }); } return handler(request);}Migration guidance and its limits
Both findings carry an assisted fix at medium confidence. Name a model provider on the command line or in emendant.json and emendant fix tries them; without one they are reported with their guidance and nothing is sent anywhere. Review whether the changed members affect your code before applying a patch. A site that names these types without reading the changed members may need no edit. Emendant checks each patch in a copy of your repository at 1.2.13 and withholds patches that fail. Read the patch header to see which checks passed.
In each wrapToolCall that reads request.tool, handle undefined first: supply the tool if your middleware registers it dynamically, or pass the request on unchanged. Where code of your own takes DefaultMiddlewareTypeConfig["Schema"] and treats it as a Zod object, narrow it before calling Zod methods on it.
The scan reports the two names in a type position when they are imported from langchain. A wrapToolCall written inline in createMiddleware({ ... }), with its parameter type inferred, is not a finding, although the compiler will flag an unguarded read there. A clean scan says no file names these two types from langchain, and nothing more about the release.
What Emendant detects, fixes and verifies
2 changes in langchain 1.2.13. 0 automatic fixes, 2 fixes requiring a model provider you choose, 0 report only. Each patch states which checks passed. Understand patch evidence.
| Change | Severity | Detects | Fix | Verified by |
|---|---|---|---|---|
Changed the members of DefaultMiddlewareTypeConfiglangchain-npm-1.2.13-default-middleware-type-config-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of ToolCallRequestlangchain-npm-1.2.13-tool-call-request-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
emendant explain <change-id> prints any row's entry, guidance and sources at the terminal.
Requires emendant@0.3.0 or later. Feed entry feed/npm/langchain/1.2.13.json, snapshot 2026-09-23.5.
Primary sources
LangChain.js 1.2.24: ReactAgent.stream gains a TSubgraphs type parameter
langchain@1.2.24 fixes the streaming types on ReactAgent. stream gains a TSubgraphs type parameter between the stream mode and the encoding, the subgraphs option is accepted, and the chunk type follows it where 1.2.23 fixed it to false. Code that passes type arguments to agent.stream explicitly, or that implements the ReactAgent shape, is what breaks.
What changed
streamhas three type parameters. They were<TStreamMode, TEncoding>and are now<TStreamMode, TSubgraphs extends boolean, TEncoding>. A call that lets them be inferred keeps compiling. A call that spells out two type arguments now puts the encoding whereTSubgraphsis expected.- The chunk type follows
subgraphs. 1.2.23 returnedStreamOutputMap<TStreamMode, false, ...>whatever was passed. 1.2.24 passesTSubgraphsthrough, so a stream withsubgraphs: trueis typed with the namespaced chunks LangGraph yields. streamEventstakes the same configuration. Its config type gains thebooleanargument for subgraphs, and its return type is unchanged.
Before and after
The affected type is imported from this module:
import type { ReactAgent } from 'langchain';The return type of stream as langchain@1.2.23 declared it:
Promise<IterableReadableStream<StreamOutputMap<TStreamMode, false, MergedAgentState<Types>, MergedAgentState<Types>, string, unknown, unknown, TEncoding>>>And as 1.2.24 declares it:
Promise<IterableReadableStream<StreamOutputMap<TStreamMode, TSubgraphs, MergedAgentState<Types>, MergedAgentState<Types>, string, unknown, unknown, TEncoding>>>Migration guidance and its limits
The finding carries an assisted fix at medium confidence. Name a model provider on the command line or in emendant.json and emendant fix tries it. Without one, it is reported with its guidance and nothing is sent anywhere. Review whether the changed members affect your code before applying a patch. Emendant checks each patch in a copy of your repository at 1.2.24 and withholds patches that fail. Read the patch header to see which checks passed.
Where code calls agent.stream<Mode, Encoding>(...), insert the subgraphs argument, agent.stream<Mode, false, Encoding>(...), or drop the type arguments and let them be inferred. Where code passes subgraphs: true, which 1.2.23’s config type did not accept, the chunks are now typed as the namespaced tuples LangGraph yields, and code reading them as plain chunks stops compiling.
The scan reports ReactAgent in a type position when it is imported from langchain. A stream call with explicit type arguments on an agent whose type is inferred from createAgent is not a finding, although the compiler still reports it. A clean scan says no file names ReactAgent from langchain, and nothing more about the release.
What Emendant detects, fixes and verifies
1 change in langchain 1.2.24. 0 automatic fixes, 1 fixes requiring a model provider you choose, 0 report only. Each patch states which checks passed. Understand patch evidence.
| Change | Severity | Detects | Fix | Verified by |
|---|---|---|---|---|
Changed the members of ReactAgentlangchain-npm-1.2.24-react-agent-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
emendant explain <change-id> prints any row's entry, guidance and sources at the terminal.
Requires emendant@0.3.0 or later. Feed entry feed/npm/langchain/1.2.24.json, snapshot 2026-09-23.6.
Primary sources
LangChain.js 1.2.29: ConfigurableModel.withStructuredOutput accepts a Standard Schema
langchain@1.2.29 adds Standard Schema support for structured output. It raises its @langchain/core range from ^1.1.29 to ^1.1.30, where withStructuredOutput gains overloads taking a SerializableSchema. ConfigurableModel, the model initChatModel returns, declares withStructuredOutput as BaseChatModel["withStructuredOutput"], so it gains them too. Calls written for 1.2.28 keep compiling. Code that assigns its own function to withStructuredOutput, or implements ConfigurableModel by hand, is what breaks.
What changed
withStructuredOutputtakes aSerializableSchema. The declaration inlangchainis unchanged,withStructuredOutput: BaseChatModel["withStructuredOutput"]. What it resolves to changed with core: 1.1.30 adds one overload returning the parsed output and one withincludeRawreturning{ raw, parsed }, each taking a schema that implements Standard Schema V1 and Standard JSON Schema V1. Zod and JSON schemas keep working.- The range moved, not the file. Only
agents/middleware/types.d.tsandagents/responses.d.tsdiffer between the two releases’ declarations. The changelog lists “implement standard schema support for structured output” and the core update.
Before and after
The affected type is imported from this module:
import type { ConfigurableModel } from 'langchain/chat_models/universal';The member as langchain@1.2.29 declares it, which is the same line as in 1.2.28:
withStructuredOutput: BaseChatModel["withStructuredOutput"];And the overload it gains through BaseChatModel in @langchain/core@1.1.30:
withStructuredOutput<RunOutput extends Record<string, any> = Record<string, any>>(outputSchema: SerializableSchema<RunOutput>, config?: StructuredOutputMethodOptions<false>): Runnable<BaseLanguageModelInput, RunOutput>;Migration guidance and its limits
The finding carries an assisted fix at medium confidence. Name a model provider on the command line or in emendant.json and emendant fix tries it. Without one, it is reported with its guidance and nothing is sent anywhere. Review whether the changed members affect your code before applying a patch. Code that only calls it may need no edit. Emendant checks each patch in a copy of your repository at 1.2.29 and withholds patches that fail. Read the patch header to see which checks passed.
Where a subclass or a mock assigns its own withStructuredOutput, it must accept the two SerializableSchema overloads as well. The type is exported from @langchain/core/utils/standard_schema.
The scan reports ConfigurableModel in a type position when it is imported from langchain/chat_models/universal. A model from initChatModel whose type is inferred is not a finding. The structured output retry fix in this release is a behaviour change the feed does not cover. A clean scan says no file names ConfigurableModel from that module, and nothing more about the release.
What Emendant detects, fixes and verifies
1 change in langchain 1.2.29. 0 automatic fixes, 1 fixes requiring a model provider you choose, 0 report only. Each patch states which checks passed. Understand patch evidence.
| Change | Severity | Detects | Fix | Verified by |
|---|---|---|---|---|
Changed the members of ConfigurableModellangchain-npm-1.2.29-chat-models-universal-configurable-model-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
emendant explain <change-id> prints any row's entry, guidance and sources at the terminal.
Requires emendant@0.3.0 or later. Feed entry feed/npm/langchain/1.2.29.json, snapshot 2026-09-23.7.
Primary sources
LangChain.js 1.2.35: ReactAgent.getSubgraphAsync renamed to getSubgraphsAsync
langchain@1.2.35 renames ReactAgent.getSubgraphAsync to getSubgraphsAsync, so the agent method now has the same name as the LangGraph method it delegates to. The old name is gone rather than deprecated. The method is marked @internal, so this affects only code that reaches into an agent’s graph API directly, such as a harness or a server that treats the agent as a compiled graph.
What changed
getSubgraphAsyncis nowgetSubgraphsAsync. The parameters are the same,(namespace?: string, recurse?: boolean), and so is the declared return type,never. In both releases the method passes its arguments to the compiled graph’sgetSubgraphsAsync, so only the name onReactAgentchanged. The changelog lists it as a fix.
Before and after
The affected type is imported from this module:
import type { ReactAgent } from 'langchain';The method as langchain@1.2.34 declared it:
getSubgraphAsync(namespace?: string, recurse?: boolean): never;And as 1.2.35 declares it:
getSubgraphsAsync(namespace?: string, recurse?: boolean): never;Migration guidance and its limits
The finding carries an assisted fix at medium confidence. Name a model provider on the command line or in emendant.json and emendant fix tries it. Without one, it is reported with its guidance and nothing is sent anywhere. Review whether the changed members affect your code before applying a patch. Most sites that name the type may need no edit. Emendant checks each patch in a copy of your repository at 1.2.35 and withholds patches that fail. Read the patch header to see which checks passed.
Where code calls agent.getSubgraphAsync(...), rename the call to getSubgraphsAsync. Code that implements the ReactAgent shape structurally must rename the method too.
The scan reports ReactAgent in a type position when it is imported from langchain. A call to getSubgraphAsync on an agent whose type is inferred from createAgent is not a finding, although the compiler still reports it. A clean scan says no file names ReactAgent from langchain, and nothing more about the release.
What Emendant detects, fixes and verifies
1 change in langchain 1.2.35. 0 automatic fixes, 1 fixes requiring a model provider you choose, 0 report only. Each patch states which checks passed. Understand patch evidence.
| Change | Severity | Detects | Fix | Verified by |
|---|---|---|---|---|
Changed the members of ReactAgentlangchain-npm-1.2.35-react-agent-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
emendant explain <change-id> prints any row's entry, guidance and sources at the terminal.
Requires emendant@0.3.0 or later. Feed entry feed/npm/langchain/1.2.35.json, snapshot 2026-09-23.6.
Primary sources
LangChain.js 1.2.36: ConfigurableModel requires getLsParamsWithDefaults and retypes withStructuredOutput
langchain@1.2.36 raises its @langchain/core peer range from ^1.1.34 to ^1.1.35. ConfigurableModel, the model initChatModel returns, extends core’s BaseChatModel, so it takes on two changes from core 1.1.35: a new required method, and withStructuredOutput overloads that name structural Zod interfaces instead of Zod’s own types. Code that calls the model keeps its shape. Code that implements ConfigurableModel by hand, or assigns its own function to withStructuredOutput, is what can break.
What changed
getLsParamsWithDefaultsis required. Core 1.1.35 declares it onBaseChatModelwith the signature(options: this["ParsedCallOptions"]): LangSmithParams. It returns whatgetLsParamsreturns withls_integrationadded. A subclass inherits it. An object written to theConfigurableModeltype does not, and must now supply it. The changelog lists “Add LangSmith integration metadata to createAgent and initChatModel.”withStructuredOutputnamesZodV4LikeandZodV3Like. The declaration inlangchainis unchanged,withStructuredOutput: BaseChatModel["withStructuredOutput"]. In core, the schema parameter of the Zod overloads changes from$ZodType<RunOutput>andZodType<RunOutput>to the interfacesZodV4Like<RunOutput>andZodV3Like<RunOutput>. The core changelog says this replaces exported Zod type references with structural interfaces, to stop TypeScript running out of memory in monorepos.- The range moved, not the file. Between 1.2.35 and 1.2.36 the only declaration that differs is
agents/tests/utils.d.ts. At runtime,initChatModeladdsls_integrationto the model’smetadata.
Before and after
The affected type is imported from this module:
import type { ConfigurableModel } from 'langchain/chat_models/universal';The first Zod v4 overload as @langchain/core@1.1.34 declared it:
withStructuredOutput<RunOutput extends Record<string, any> = Record<string, any>>(outputSchema: $ZodType<RunOutput> | Record<string, any>, config?: StructuredOutputMethodOptions<false>): Runnable<BaseLanguageModelInput, RunOutput>;And as 1.1.35 declares it, with the member it adds:
getLsParamsWithDefaults(options: this["ParsedCallOptions"]): LangSmithParams;
withStructuredOutput<RunOutput extends Record<string, any> = Record<string, any>>(outputSchema: ZodV4Like<RunOutput> | Record<string, any>, config?: StructuredOutputMethodOptions<false>): Runnable<BaseLanguageModelInput, RunOutput>;The Zod v3 overloads change the same way, from ZodType<RunOutput> to ZodV3Like<RunOutput>.
Migration guidance and its limits
The finding carries an assisted fix at medium confidence. Name a model provider on the command line or in emendant.json and emendant fix tries it. Without one, it is reported with its guidance and nothing is sent anywhere. Review whether the changed members affect your code before applying a patch. Most sites that only annotate a variable may need no edit. Emendant checks each patch in a copy of your repository at 1.2.36 and withholds patches that fail. Read the patch header to see which checks passed.
Where you build a ConfigurableModel shape yourself, for example a test double, add getLsParamsWithDefaults. Where you assign a function to withStructuredOutput, type its schema parameter with ZodV4Like or ZodV3Like from @langchain/core/utils/types, or type the function as BaseChatModel["withStructuredOutput"].
The scan reports ConfigurableModel in a type position when it is imported from langchain/chat_models/universal. A model whose type is inferred from initChatModel is not a finding, although the compiler still checks it. A clean scan says no file names ConfigurableModel from that module, and nothing more about the release.
What Emendant detects, fixes and verifies
1 change in langchain 1.2.36. 0 automatic fixes, 1 fixes requiring a model provider you choose, 0 report only. Each patch states which checks passed. Understand patch evidence.
| Change | Severity | Detects | Fix | Verified by |
|---|---|---|---|---|
Changed the members of ConfigurableModellangchain-npm-1.2.36-chat-models-universal-configurable-model-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
emendant explain <change-id> prints any row's entry, guidance and sources at the terminal.
Requires emendant@0.3.0 or later. Feed entry feed/npm/langchain/1.2.36.json, snapshot 2026-09-23.8.
Primary sources
LangChain.js 1.2.39: agents accept any runnable model, typed as AgentLanguageModelLike
langchain@1.2.39 lets createAgent accept runnable models from other versions of @langchain/core, and lets middleware change structured output per step. The model an agent is given, and the model a wrapModelCall middleware receives on ModelRequest, are now typed AgentLanguageModelLike, which is a RunnableInterface rather than the LanguageModelLike class type. Passing a model in keeps compiling. Middleware that reads request.model and uses it as the old type is what can break.
What changed
modelisAgentLanguageModelLike. It is declared asRunnableInterface<BaseLanguageModelInput, LanguageModelOutput>. OnCreateAgentParamsthe member changes fromstring | LanguageModelLiketostring | AgentLanguageModelLike, and onModelRequestfromLanguageModelLiketoAgentLanguageModelLike. The changelog lists it as “accept cross-version runnable models in createAgent.”ModelRequestgainsresponseFormat. It is optional, and its documentation says middleware can override it to enable or change structured output for the step. The changelog lists “add support for dynamic structured output.”- Both types are exported twice.
langchainandlangchain/browserexport each, and the feed has a row for each, so the table lists four.
Before and after
The affected type is imported from this module:
import type { ModelRequest } from 'langchain';The member on ModelRequest as langchain@1.2.38 declared it:
model: LanguageModelLike;And as 1.2.39 declares it:
model: AgentLanguageModelLike;
type AgentLanguageModelLike = RunnableInterface<BaseLanguageModelInput, LanguageModelOutput>;Migration guidance and its limits
All four findings carry an assisted fix at medium confidence. Name a model provider on the command line or in emendant.json and emendant fix tries them; without one they are reported with their guidance and nothing is sent anywhere. Review whether the changed members affect your code before applying a patch. Sites that only pass a model in may need no edit. Emendant checks each patch in a copy of your repository at 1.2.39 and withholds patches that fail. Read the patch header to see which checks passed.
In middleware, check what you do with request.model. Calls that RunnableInterface declares, such as invoke and stream, still type check. Assigning it to a variable typed LanguageModelLike, or calling a method only the Runnable class has, does not; narrow the value first or type your variable with AgentLanguageModelLike.
The scan reports the two names in a type position when they are imported from langchain or langchain/browser. A wrapModelCall written inline, with its request type inferred, is not a finding, although the compiler still checks it. A clean scan says no file names these two types from those modules, and nothing more about the release.
What Emendant detects, fixes and verifies
4 changes in langchain 1.2.39. 0 automatic fixes, 4 fixes requiring a model provider you choose, 0 report only. Each patch states which checks passed. Understand patch evidence.
| Change | Severity | Detects | Fix | Verified by |
|---|---|---|---|---|
Changed the members of CreateAgentParamslangchain-npm-1.2.39-create-agent-params-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of ModelRequestlangchain-npm-1.2.39-model-request-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of CreateAgentParamslangchain-npm-1.2.39-browser-create-agent-params-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of ModelRequestlangchain-npm-1.2.39-browser-model-request-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
emendant explain <change-id> prints any row's entry, guidance and sources at the terminal.
Requires emendant@0.3.0 or later. Feed entry feed/npm/langchain/1.2.39.json, snapshot 2026-09-23.4.
Primary sources
LangChain.js 1.4.0: streamEvents v3 for agents, and AgentTypeConfig requires StreamTransformers
langchain@1.4.0 adopts the new streaming primitives in @langchain/langgraph 1.3. A ReactAgent gains a streamEvents overload for version: "v3", which resolves to an AgentRunStream, and createAgent accepts streamTransformers whose projections appear on run.extensions. To type them, AgentTypeConfig and DefaultAgentTypeConfig gain a required StreamTransformers member. Code that declares an agent’s type config by hand, or reads agent.builder for its state types, is what can break.
What changed
AgentTypeConfigrequiresStreamTransformers. The interface gains a sixth type parameter, which defaults toReadonlyArray<() => StreamTransformer<any>>, and a member of that type.DefaultAgentTypeConfigdeclares it asreadonly []. A reference that passes five type arguments still compiles.ReactAgent.streamEventstakesversion: "v3". The new overload returnsPromise<AgentRunStream<...>>rather than anIterableReadableStream, and it accepts call-sitetransformers. Calls with"v1","v2"or no version keep their old overloads.ReactAgent.builderis less precise. It was aStateGraphtyped with the agent’s merged state and context. In 1.4.0 those type arguments areany.- Each type is exported twice.
langchainandlangchain/browserexport all three, and the feed has a row for each, so the table lists six.
Before and after
The affected type is imported from this module:
import type { AgentTypeConfig } from 'langchain';The streamEvents overload langchain@1.4.0 adds to ReactAgent, with the config type shortened:
streamEvents(state: InvokeStateParameter<Types>, config: InvokeConfiguration<...> & { version: "v3"; transformers?: ReadonlyArray<() => StreamTransformer<any>>;}): Promise<AgentRunStream<MergedAgentState<Types>, Types["Tools"], InferStreamExtensions<Types["StreamTransformers"]>>>;And the member DefaultAgentTypeConfig gains:
StreamTransformers: readonly [];Migration guidance and its limits
All six findings carry an assisted fix at medium confidence. Name a model provider on the command line or in emendant.json and emendant fix tries them. Without one, they are reported with their guidance and nothing is sent anywhere. Review whether the changed members affect your code before applying a patch. Emendant checks each patch in a copy of your repository at 1.4.0 and withholds patches that fail. Read the patch header to see which checks passed.
Where code declares an object type as an AgentTypeConfig, add StreamTransformers. Where code read state or context types off agent.builder, it now gets any and should take them from InferAgentState or InferAgentContext instead. To use the v3 stream, await the result of streamEvents before iterating it.
The scan reports the three names in a type position when they are imported from langchain or langchain/browser. An agent made with createAgent whose type is inferred is not a finding, although the compiler still checks it. The release also raises its @langchain/langgraph range to ^1.3.0, which the feed does not describe. A clean scan says no file names these types from those two modules, and nothing more about the release.
What Emendant detects, fixes and verifies
6 changes in langchain 1.4.0. 0 automatic fixes, 6 fixes requiring a model provider you choose, 0 report only. Each patch states which checks passed. Understand patch evidence.
| Change | Severity | Detects | Fix | Verified by |
|---|---|---|---|---|
Changed the members of AgentTypeConfiglangchain-npm-1.4.0-agent-type-config-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of DefaultAgentTypeConfiglangchain-npm-1.4.0-default-agent-type-config-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of ReactAgentlangchain-npm-1.4.0-react-agent-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of AgentTypeConfiglangchain-npm-1.4.0-browser-agent-type-config-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of DefaultAgentTypeConfiglangchain-npm-1.4.0-browser-default-agent-type-config-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of ReactAgentlangchain-npm-1.4.0-browser-react-agent-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
emendant explain <change-id> prints any row's entry, guidance and sources at the terminal.
Requires emendant@0.3.0 or later. Feed entry feed/npm/langchain/1.4.0.json, snapshot 2026-09-23.6.
Primary sources
LangChain.js 1.4.1: @langchain/core 1.1.47 deprecates streamEvents v1 on tools and fake models
langchain@1.4.1 raises its @langchain/core range from ^1.1.44 to ^1.1.47. Every Runnable in that core declares streamEvents once per version, and marks the "v1" forms and streamLog as deprecated. langchain ships no declaration changes of its own in this release, so what reaches your code is the new core, through two types langchain exports.
What changed
streamEventshas an overload perversion.@langchain/core@1.1.44declared two overloads, both takingversion: "v1" | "v2". From 1.1.45 there are six:"v2", then the deprecated"v1", then the old union, each with and withoutencoding: "text/event-stream".streamLogis marked deprecated in favour of.stream().HeadlessToolandFakeToolCallingModelinherit them. Both are runnables, so both change with core.HeadlessToolis exported fromlangchain,langchain/browserandlangchain/tools, andFakeToolCallingModelfromlangchainandlangchain/browser. The feed has one row per module, so the table lists five.
Before and after
The affected type is imported from this module:
import type { HeadlessTool } from 'langchain/tools';streamEvents on Runnable in @langchain/core@1.1.44:
streamEvents(input: RunInput, options: Partial<CallOptions> & { version: "v1" | "v2";}, streamOptions?: Omit<EventStreamCallbackHandlerInput, "autoClose">): IterableReadableStream<StreamEvent>;And the first of the overloads in 1.1.47, the floor of the range 1.4.1 requires:
streamEvents(input: RunInput, options: Partial<CallOptions> & { version: "v2";}, streamOptions?: Omit<EventStreamCallbackHandlerInput, "autoClose">): IterableReadableStream<StreamEvent>;Migration guidance and its limits
All five findings carry an assisted fix at medium confidence. Name a model provider on the command line or in emendant.json and emendant fix tries them. Without one, they are reported with their guidance and nothing is sent anywhere. Review whether the changed members affect your code before applying a patch. Calls with "v1", "v2" or the union still compile and may need no edit. Emendant checks each patch in a copy of your repository at 1.4.1 and withholds patches that fail. Read the patch header to see which checks passed.
Move streamEvents calls from version: "v1" to "v2", and streamLog calls to .stream(), before a later release removes them. Code that implements either type structurally must declare the new overloads.
The scan reports the two names in a type position when they are imported from the modules above. A streamEvents or streamLog call on any other runnable is not a finding. The fix in this release for providerStrategy parse failures, which now throw, is a behaviour change the feed does not cover. A clean scan says no file names these types from those modules, and nothing more about the release.
What Emendant detects, fixes and verifies
5 changes in langchain 1.4.1. 0 automatic fixes, 5 fixes requiring a model provider you choose, 0 report only. Each patch states which checks passed. Understand patch evidence.
| Change | Severity | Detects | Fix | Verified by |
|---|---|---|---|---|
Changed the members of FakeToolCallingModellangchain-npm-1.4.1-fake-tool-calling-model-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of HeadlessToollangchain-npm-1.4.1-headless-tool-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of FakeToolCallingModellangchain-npm-1.4.1-browser-fake-tool-calling-model-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of HeadlessToollangchain-npm-1.4.1-browser-headless-tool-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of HeadlessToollangchain-npm-1.4.1-tools-headless-tool-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
emendant explain <change-id> prints any row's entry, guidance and sources at the terminal.
Requires emendant@0.3.0 or later. Feed entry feed/npm/langchain/1.4.1.json, snapshot 2026-09-23.6.
Primary sources
LangChain.js 1.4.4: MiddlewareTypeConfig requires StreamTransformers
langchain@1.4.4 lets middleware register stream transformers. createMiddleware accepts streamTransformers, which are merged with the ones passed to createAgent. To carry their types, MiddlewareTypeConfig gains a fifth type parameter and a required StreamTransformers member. Code that builds or declares a MiddlewareTypeConfig by hand must now supply that member.
What changed
MiddlewareTypeConfigrequiresStreamTransformers. The interface gains a type parameterTStreamTransformers, which defaults toReadonlyArray<() => StreamTransformer<any>>, and a required memberStreamTransformers: TStreamTransformers. A reference that passes four type arguments still compiles, because the fifth has a default.CreateAgentParamsandDefaultAgentTypeConfigdeclare middleware withAnyAgentMiddleware. Themiddlewaremember ofCreateAgentParamswasreadonly AgentMiddleware[]and is nowreadonly AnyAgentMiddleware[].DefaultAgentTypeConfigfollows fromAgentTypeConfig, whose middleware default changed the same way. Code that restates either type with its own middleware array type may stop matching.DefaultMiddlewareTypeConfigrequiresStreamTransformers. It is an alias ofMiddlewareTypeConfig, so it gains the same member.AgentMiddlewaretakesstreamTransformers. The optional member holds the transformer factories, and a newAnyAgentMiddlewaretype accepts middleware with any tools or transformers. The feed does not report these two on their own, because neither requires anything new.- The changelog files this under 1.4.3. That version was never published to npm, so 1.4.4 is the first release to carry it. The feed compares 1.4.4 with 1.4.2 for that reason.
- Each type is exported twice.
langchainandlangchain/browserboth export these types, and the feed has a row for each, eight in all.
Before and after
The affected type is imported from this module:
import type { MiddlewareTypeConfig } from 'langchain';The members as langchain@1.4.2 declared them:
Schema: TSchema; ContextSchema: TContextSchema; FullContext: TFullContext; Tools: TTools;And the member 1.4.4 adds:
StreamTransformers: TStreamTransformers;Migration guidance and its limits
All eight findings carry an assisted fix at medium confidence. Name a model provider on the command line or in emendant.json and emendant fix tries them. Without one, they are reported with their guidance and nothing is sent anywhere. Review whether the changed members affect your code before applying a patch. Emendant checks each patch in a copy of your repository at 1.4.4 and withholds patches that fail. Read the patch header to see which checks passed.
MiddlewareTypeConfig is mostly read through helpers such as InferMiddlewareType, and code that only reads it needs no change. Where code declares an object type or a value as a MiddlewareTypeConfig or DefaultMiddlewareTypeConfig, add StreamTransformers, typed as the transformer factories the middleware registers. Where code restates CreateAgentParams or DefaultAgentTypeConfig with a hand-written middleware array type, use AnyAgentMiddleware for the elements.
The scan reports the name in a type position when it is imported from langchain or langchain/browser, for each of the four types. Middleware made with createMiddleware, whose config type is inferred, is not a finding, although the compiler still checks it. A clean scan says no file names these four types from those two modules, and nothing more about the release.
What Emendant detects, fixes and verifies
8 changes in langchain 1.4.4. 0 automatic fixes, 8 fixes requiring a model provider you choose, 0 report only. Each patch states which checks passed. Understand patch evidence.
| Change | Severity | Detects | Fix | Verified by |
|---|---|---|---|---|
Changed the members of MiddlewareTypeConfiglangchain-npm-1.4.4-middleware-type-config-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of MiddlewareTypeConfiglangchain-npm-1.4.4-browser-middleware-type-config-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of CreateAgentParamslangchain-npm-1.4.4-create-agent-params-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of DefaultAgentTypeConfiglangchain-npm-1.4.4-default-agent-type-config-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of DefaultMiddlewareTypeConfiglangchain-npm-1.4.4-default-middleware-type-config-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of CreateAgentParamslangchain-npm-1.4.4-browser-create-agent-params-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of DefaultAgentTypeConfiglangchain-npm-1.4.4-browser-default-agent-type-config-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of DefaultMiddlewareTypeConfiglangchain-npm-1.4.4-browser-default-middleware-type-config-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
emendant explain <change-id> prints any row's entry, guidance and sources at the terminal.
Requires emendant@0.3.0 or later. Feed entry feed/npm/langchain/1.4.4.json, snapshot 2026-10-05.1.
Primary sources
LangChain.js 1.4.6: streamEvents without a version, and a when predicate for human review
langchain@1.4.6 raises its @langchain/core range from ^1.1.49 to ^1.2.0, and its chat models take that release’s streamEvents. Called without a version, streamEvents now returns a ChatModelStream of content blocks, and the "v1" and "v2" forms are deprecated. The same release adds an optional when predicate to each interruptOn entry of the human-in-the-loop middleware.
What changed
streamEventsis overloaded byversion.ConfigurableModel, whichinitChatModelreturns, used to declare one overload takingversion: "v1" | "v2". It now declares a deprecated overload for"v2"and one for"v1", each with and withoutencoding: "text/event-stream", and a new one with noversionthat returnsChatModelStream.FakeToolCallingModelgets the same set fromBaseChatModelin@langchain/core@1.2.0.interruptOnentries takewhen.InterruptOnConfiggainswhen?: (request: ToolCallRequest) => boolean | Promise<boolean>, andHumanInTheLoopMiddlewareConfig.interruptOnis declared with it. Whenwhenreturnsfalse, the tool call is approved without an interrupt. The type is exported asWhenPredicate.- Each type is exported from more than one module.
FakeToolCallingModelandHumanInTheLoopMiddlewareConfigcome fromlangchainand fromlangchain/browser, andConfigurableModelfromlangchain/chat_models/universal. The feed has one row per module, so the table lists five.
Before and after
The affected type is imported from this module:
import type { ConfigurableModel } from 'langchain/chat_models/universal';streamEvents on ConfigurableModel as langchain@1.4.5 declared it:
streamEvents(input: RunInput, options: Partial<CallOptions> & { version: "v1" | "v2";}, streamOptions?: Omit<EventStreamCallbackHandlerInput, "autoClose">): IterableReadableStream<StreamEvent>;And the overload 1.4.6 adds beside the deprecated ones:
streamEvents(input: RunInput, options?: Partial<CallOptions>): ChatModelStream;Migration guidance and its limits
All five findings carry an assisted fix at medium confidence. Name a model provider on the command line or in emendant.json and emendant fix tries them. Without one, they are reported with their guidance and nothing is sent anywhere. Review whether the changed members affect your code before applying a patch. Emendant checks each patch in a copy of your repository at 1.4.6 and withholds patches that fail. Read the patch header to see which checks passed.
A call that passes a literal version: "v2" still compiles, and is now deprecated. On ConfigurableModel, a version typed as the union "v1" | "v2" no longer matches a deprecated overload: narrow it to one literal, or drop version and read the ChatModelStream. Code that implements ConfigurableModel or FakeToolCallingModel structurally must declare the new overloads. The new when member is optional and affects no code that does not set it.
The scan reports the three names in a type position when they are imported from the modules above. A streamEvents call on a model whose type is inferred, such as the result of initChatModel in an unannotated variable, is not a finding, although the compiler still checks it. bedrockPromptCachingMiddleware, also new in this release, is not covered. A clean scan says no file names these types from those modules, and nothing more about the release.
What Emendant detects, fixes and verifies
5 changes in langchain 1.4.6. 0 automatic fixes, 5 fixes requiring a model provider you choose, 0 report only. Each patch states which checks passed. Understand patch evidence.
| Change | Severity | Detects | Fix | Verified by |
|---|---|---|---|---|
Changed the members of FakeToolCallingModellangchain-npm-1.4.6-fake-tool-calling-model-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of HumanInTheLoopMiddlewareConfiglangchain-npm-1.4.6-human-in-the-loop-middleware-config-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of FakeToolCallingModellangchain-npm-1.4.6-browser-fake-tool-calling-model-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of HumanInTheLoopMiddlewareConfiglangchain-npm-1.4.6-browser-human-in-the-loop-middleware-config-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of ConfigurableModellangchain-npm-1.4.6-chat-models-universal-configurable-model-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
emendant explain <change-id> prints any row's entry, guidance and sources at the terminal.
Requires emendant@0.3.0 or later. Feed entry feed/npm/langchain/1.4.6.json, snapshot 2026-09-23.6.
Primary sources
LangChain.js 1.5.3: MiddlewareError's ~brand moves onto the instance
langchain@1.5.3 moves the "~brand" marker on MiddlewareError from the class to each instance, so error["~brand"] reads "MiddlewareError". The error type has no private members, so an object shaped like one could be typed as one before. After the upgrade such an object must carry the brand. Errors made with MiddlewareError.wrap() need nothing.
What changed
"~brand"is an instance member. 1.5.2 declaredstatic readonly "~brand" = "MiddlewareError"; 1.5.3 declaresreadonly "~brand" = "MiddlewareError"on the instance and no static one.ToolInvocationErrorcarries an instance brand of its own in the same file. The package exports the type fromlangchainand fromlangchain/browser, and the feed has a row for each.
Before and after
The affected type is imported from this module:
import type { MiddlewareError } from 'langchain';The member as langchain@1.5.2 declared it:
declare class MiddlewareError extends Error { static readonly "~brand" = "MiddlewareError";And as 1.5.3 declares it:
declare class MiddlewareError extends Error { readonly "~brand" = "MiddlewareError";Migration guidance and its limits
Both findings carry an assisted fix at medium confidence. Name a model provider on the command line or in emendant.json and emendant fix tries them; without one they are reported with their guidance and nothing is sent anywhere. Review whether the changed members affect your code before applying a patch. A site that names the type only to narrow a caught error may need no edit. Emendant checks each patch in a copy of your repository at 1.5.3 and withholds patches that fail. Read the patch header to see which checks passed.
Where a test or a mock builds a plain object typed MiddlewareError, add "~brand": "MiddlewareError" or build the error with MiddlewareError.wrap(). Code that read the static MiddlewareError["~brand"] must read it from an instance, or compare against the string.
The scan reports the name in a type position when it is imported from langchain or langchain/browser. A read of the static brand is not a finding by itself. The release’s changelog entry, about malformed tool input schemas, is not covered. A clean scan says no file names MiddlewareError from those two modules, and nothing more about the release.
What Emendant detects, fixes and verifies
2 changes in langchain 1.5.3. 0 automatic fixes, 2 fixes requiring a model provider you choose, 0 report only. Each patch states which checks passed. Understand patch evidence.
| Change | Severity | Detects | Fix | Verified by |
|---|---|---|---|---|
Changed the members of MiddlewareErrorlangchain-npm-1.5.3-middleware-error-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of MiddlewareErrorlangchain-npm-1.5.3-browser-middleware-error-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
emendant explain <change-id> prints any row's entry, guidance and sources at the terminal.
Requires emendant@0.3.0 or later. Feed entry feed/npm/langchain/1.5.3.json, snapshot 2026-09-23.4.
Primary sources
langchain@1.5.16: piiRedactionMiddleware and PIIRedactionMiddlewareConfig deprecated
langchain@1.5.16 ships declarations that mark piiRedactionMiddleware and PIIRedactionMiddlewareConfig as @deprecated, in both langchain and langchain/browser. Both are still exported and still work, so nothing fails to build or run. Code that imports either name from either module is affected.
What changed
- Two names are deprecated.
piiRedactionMiddlewareis the function that redacts PII before messages reach a model provider.PIIRedactionMiddlewareConfigis the type of its options. The declaration carries a bare@deprecatedtag and names no replacement. - Both entry points are covered. Each name is exported from
langchainand fromlangchain/browser, so an import from either module is a finding. That makes four findings in all. - Nothing is removed. The only changelog entry for 1.5.16 is a
createAgentfix about aCommandbuilt by a different copy of@langchain/langgraph, and it does not mention these names. The 1.5.15 declaration files already carry the same@deprecatedtag, so the deprecation may predate this release.
Before and after
This import is the one most projects will meet:
import { piiRedactionMiddleware } from 'langchain';
export { piiRedactionMiddleware };There is no deterministic rewrite for it. The release does not name a replacement, so the assisted patch changes this import only where a direct replacement with the same behaviour can be identified. Otherwise the import stays as written and keeps working at 1.5.16.
The other three findings have the same shape: PIIRedactionMiddlewareConfig from langchain, and both names from langchain/browser.
Migration guidance and its limits
All four findings carry an assisted fix, and none is report only. Name a model provider on the command line or in your Emendant config, then run emendant fix. Without a provider, the findings are reported with their guidance and nothing is sent anywhere.
A patch rewrites a site only where the release provides a direct replacement with the same behaviour. It never changes what your code does in order to move off the name. The declarations name no replacement, so a patch may not be available for a given site. In that case the deprecated import still works at this release, and the remaining step is to choose a replacement yourself. Each patch is checked in a copy of your repository at 1.5.16 against your own typecheck and tests, where it finds them. Read the patch header to see which checks ran.
Redaction is a privacy control, so review any applied patch against the tests that cover your redaction rules before you merge it.
The scan matches named imports of the two names from langchain and langchain/browser. An import of a same-named export from another module, such as a local compatibility file, is not a finding. A clean scan means no such named import remains. It does not prove that the deprecated middleware is out of your code by other routes.
What Emendant detects, fixes and verifies
4 changes in langchain 1.5.16. 0 automatic fixes, 4 fixes requiring a model provider you choose, 0 report only. Each patch states which checks passed. Understand patch evidence.
| Change | Severity | Detects | Fix | Verified by |
|---|---|---|---|---|
Deprecated PIIRedactionMiddlewareConfiglangchain-npm-1.5.16-piiredaction-middleware-config-deprecated | Deprecation |
| Patch, only when you name a model provider | Your typecheck and tests |
Deprecated piiRedactionMiddlewarelangchain-npm-1.5.16-pii-redaction-middleware-deprecated | Deprecation |
| Patch, only when you name a model provider | Your typecheck and tests |
Deprecated PIIRedactionMiddlewareConfiglangchain-npm-1.5.16-browser-piiredaction-middleware-config-deprecated | Deprecation |
| Patch, only when you name a model provider | Your typecheck and tests |
Deprecated piiRedactionMiddlewarelangchain-npm-1.5.16-browser-pii-redaction-middleware-deprecated | Deprecation |
| Patch, only when you name a model provider | Your typecheck and tests |
emendant explain <change-id> prints any row's entry, guidance and sources at the terminal.
Requires emendant@0.1.0 or later. Feed entry feed/npm/langchain/1.5.16.json, snapshot 2026-10-08.3.
Primary sources
langchain@1.5.17: InterruptOnConfig and HumanInTheLoopMiddlewareConfig members changed
langchain@1.5.17 adds a respond decision to the human-in-the-loop middleware, and the declared types of allowedDecisions and interruptOn change with it. Code that names InterruptOnConfig or HumanInTheLoopMiddlewareConfig, imported from langchain or langchain/browser, is affected. Nothing is removed.
What changed
allowedDecisionsonInterruptOnConfighas a wider element type. In 1.5.16 the elements wereapprove,editorreject. In 1.5.17 they can also berespond. The changelog files this as support for HITL respond decisions.interruptOnonHumanInTheLoopMiddlewareConfigchanges with it. Its per-tool entries areInterruptOnConfigobjects, so the same wider type reaches any code that builds or reads that mapping.- Both entry points are affected. Each type is exported from
langchainand fromlangchain/browser, so an import from either module is a finding.
Before and after
No finding for this release has a deterministic rewrite. This is the kind of import the scan reports:
import type { InterruptOnConfig } from 'langchain';The shape change behind it, as declared for allowedDecisions in 1.5.16:
allowedDecisions: ("approve" | "edit" | "reject")[];And in 1.5.17:
allowedDecisions: ("approve" | "edit" | "reject" | "respond")[];The other three findings have the same form: HumanInTheLoopMiddlewareConfig from langchain, and both types from langchain/browser.
Migration guidance and its limits
All four findings carry an assisted fix, and none is report only. Name a model provider on the command line or in your Emendant config, then run emendant fix. Without a provider, the findings are reported with their guidance and nothing is sent anywhere.
A patch edits a site only where your code supplies or reads allowedDecisions or interruptOn. Code that only names the type, for example to pass a config along, may need no edit, and a patch may not be available for it. Where a patch applies, it brings that code into line with the 1.5.17 declarations and changes nothing else. Each patch is checked in a copy of your repository against your own typecheck and tests, where it finds them. Read the patch header to see which checks ran.
The patch cannot decide what your human-in-the-loop flow should do with a respond decision. If your code switches over the values in allowedDecisions and expects only approve, edit and reject, review how it should handle the new value.
The scan matches the two type names in a type position when they are imported from langchain or langchain/browser. A same-named export from another module, such as a local compatibility file, is not a finding. A clean scan means no file names these types from those two modules. It does not show that code reaching the same config through inference, for instance as an argument to humanInTheLoopMiddleware, is unaffected, so keep your typecheck in the upgrade.
What Emendant detects, fixes and verifies
4 changes in langchain 1.5.17. 0 automatic fixes, 4 fixes requiring a model provider you choose, 0 report only. Each patch states which checks passed. Understand patch evidence.
| Change | Severity | Detects | Fix | Verified by |
|---|---|---|---|---|
Changed the members of HumanInTheLoopMiddlewareConfiglangchain-npm-1.5.17-human-in-the-loop-middleware-config-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of InterruptOnConfiglangchain-npm-1.5.17-interrupt-on-config-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of HumanInTheLoopMiddlewareConfiglangchain-npm-1.5.17-browser-human-in-the-loop-middleware-config-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of InterruptOnConfiglangchain-npm-1.5.17-browser-interrupt-on-config-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
emendant explain <change-id> prints any row's entry, guidance and sources at the terminal.
Requires emendant@0.3.0 or later. Feed entry feed/npm/langchain/1.5.17.json, snapshot 2026-10-16.2.
Primary sources
Scan your repository
Find affected code without editing your files.
npx emendant scanThen npx emendant fix writes the patches the tables say exist. Run emendant feed update first to get the latest coverage. The getting started guide covers the flags and the patch grades.
Related release pages
- LangChain 1.0 for JavaScript: the legacy modules moved to @langchain/classic
- LangChain 0.3 for JavaScript: 39 entrypoints move to @langchain/community, six are gone
The LangChain.js migration guide lists every release page and says which to read for your upgrade.