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.1.7: CallbackManager and LangChainTracer signatures change with LangSmith 0.4 2 breaking, 0 deprecations
- 1.1.25: addLangChainErrorFields deprecated 0 breaking, 1 deprecation
- 1.1.28: tool functions may be async generators 5 breaking, 0 deprecations
- 1.1.30: withStructuredOutput accepts a Standard Schema 9 breaking, 0 deprecations
- 1.1.31: fakeModel removed from utils/testing 1 breaking, 0 deprecations
- 1.1.32: DynamicStructuredTool gains a ToolEventT type parameter before NameT 4 breaking, 0 deprecations
- 1.1.35: Zod types replaced by ZodV3Like and ZodV4Like in withStructuredOutput 10 breaking, 0 deprecations
- 1.1.38: LanguageModelLike becomes a RunnableInterface 1 breaking, 0 deprecations
- 1.1.45: RunnableWithMessageHistory deprecated 0 breaking, 1 deprecation
- 1.2.0: chat model streamEvents returns a ChatModelStream without a version 6 breaking, 0 deprecations
- 1.2.18: RunUpdate members changed 1 breaking, 0 deprecations
@langchain/core 1.1.7: CallbackManager and LangChainTracer signatures change with LangSmith 0.4
@langchain/core@1.1.7 moves its langsmith dependency from ^0.3.82 to >=0.4.0 <1.0.0 and changes the tracing surface built on it. CallbackManager.handleChainStart takes two more optional parameters, and LangChainTracer gains an onLLMEnd method and types its runs against the new LangSmith BaseRun. Code that subclasses LangChainTracer or CallbackManager, or overrides these methods, is what can break. Code that only passes callbacks in is unaffected.
What changed
handleChainStarttakes_parentRunIdandextra. Both are optional and come afterrunName, so existing calls compile. An override with the old parameter list is still assignable, but cannot receive the new values.LangChainTracerdeclaresonLLMEnd. The method takes aRunand returnsvoid. The changelog says the tracer now addsusage_metadatato run metadata, which is what it does there.- Runs are typed against LangSmith 0.4.
getRun,onRunCreateandonRunUpdatekeep their names and parameters. TheRunthey use extendsBaseRunfromlangsmith, and that type now comes from 0.4._createRunForChainStart, whichLangChainTracerinherits fromBaseTracer, takes the same trailingextraparameter.
Before and after
The affected type is imported from this module:
import type { LangChainTracer } from '@langchain/core/tracers/tracer_langchain';handleChainStart as @langchain/core@1.1.6 declared it:
handleChainStart(chain: Serialized, inputs: ChainValues, runId?: string, runType?: string | undefined, _tags?: string[] | undefined, _metadata?: Record<string, unknown> | undefined, runName?: string | undefined): Promise<CallbackManagerForChainRun>;And as 1.1.7 declares it:
handleChainStart(chain: Serialized, inputs: ChainValues, runId?: string, runType?: string | undefined, _tags?: string[] | undefined, _metadata?: Record<string, unknown> | undefined, runName?: string | undefined, _parentRunId?: string | undefined, extra?: Record<string, unknown> | undefined): Promise<CallbackManagerForChainRun>;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. Emendant checks each patch in a copy of your repository at 1.1.7 and withholds patches that fail. Read the patch header to see which checks passed.
A subclass of LangChainTracer that defines its own onLLMEnd must match the new signature. One that overrides handleChainStart or _createRunForChainStart should add the new parameters and pass them on. Where your project also depends on langsmith directly, keep it inside the 0.4 range so that the two BaseRun types agree.
The scan reports the two names in a type position when they are imported from the modules above. A class that extends BaseTracer directly is not a finding. The change to how a runnable’s transform is traced, which the changelog lists for this release, 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
2 changes in @langchain/core 1.1.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 CallbackManagerlangchain-core-npm-1.1.7-callbacks-manager-callback-manager-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of LangChainTracerlangchain-core-npm-1.1.7-tracers-tracer-langchain-lang-chain-tracer-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/core/1.1.7.json, snapshot 2026-09-23.5.
Primary sources
@langchain/core 1.1.25: addLangChainErrorFields deprecated
@langchain/core 1.1.25 adds a LangChainError base class, which ModelAbortError now extends alongside a new ContextOverflowError for context window overflows. Alongside it, addLangChainErrorFields in @langchain/core/errors gains a @deprecated marker pointing readers at subclassing LangChainError instead. The function keeps its signature and keeps working; only its declaration file changed.
What changed
addLangChainErrorFieldsis deprecated, not removed. Its declaration in@langchain/core/errorsnow carries@deprecated Subclass LangChainError instead. Emendant reports each import of it from that module, so you can find every call site before the function is removed in a later major.
Before and after
A call built through the deprecated helper, with the import held in a variable-free form that the matcher attributes directly:
import { addLangChainErrorFields } from '@langchain/core/errors';
export function makeAuthError(err: unknown) { return addLangChainErrorFields(err, 'MODEL_AUTHENTICATION');}To migrate, replace the helper call with a subclass of LangChainError. The following pattern comes from the declarations for ModelAbortError and ContextOverflowError:
import { LangChainError } from '@langchain/core/errors';
class ModelAuthenticationError extends LangChainError { readonly name = 'ModelAuthenticationError';}The matcher is precise about the name it is looking for, not the local one it is bound to. An import of ContextOverflowError renamed on the way in to addLangChainErrorFields is not a use of the deprecated function, and Emendant does not report it.
Migration guidance and its limits
Emendant reports the deprecated helper and supports assisted fixes when you name a model provider. The helper still works in this release. Moving to a subclass changes the structure of your code, so review the class and its constructor before applying a patch. A patch may not be available for this migration.
What you still have to decide: whether each call site is worth converting to a LangChainError subclass now, or left until the function is actually removed. The declaration file does not say when that will be, only that it will happen.
A clean scan does not tell you that your own error handling already expects the fields addLangChainErrorFields attaches to a plain object rather than the properties a LangChainError subclass exposes on an instance. Check anywhere your code inspects the error it gets back, including logging and serialisation, before you rewrite a call site.
The matcher only follows the imported name addLangChainErrorFields from @langchain/core/errors. A reimplementation, a copy pasted version, or a call reached through a re-export from your own module is not something this entry can see.
What Emendant detects, fixes and verifies
1 change in @langchain/core 1.1.25. 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 |
|---|---|---|---|---|
Deprecated addLangChainErrorFieldslangchain-core-npm-1.1.25-errors-add-lang-chain-error-fields-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.3.0 or later. Feed entry feed/npm/@langchain/core/1.1.25.json, snapshot 2026-09-23.5.
Primary sources
@langchain/core 1.1.28: tool functions may be async generators
@langchain/core@1.1.28 lets a tool stream partial results. The func behind DynamicTool and DynamicStructuredTool may now return an async generator as well as a promise, and callback handlers gain a hook for each yielded value. Tools written for 1.1.27 keep compiling, and so do handlers. Code that calls a tool’s func directly and awaits it as a value is what breaks, because the result may now be a generator.
What changed
funcmay return anAsyncGenerator. OnDynamicToolInputandDynamicStructuredToolInput, and on thefuncmember of the two classes, the return type widens fromPromise<ToolOutputT>toPromise<ToolOutputT> | AsyncGenerator<unknown, ToolOutputT>.DynamicTool._callwidens the same way. The changelog lists “implement asynchronous generator tool calling for streaming partial tool results.”- A new callback,
handleToolEvent.BaseCallbackHandlerdeclares it as optional, called once per yielded value, andhandleToolStartgains an optional trailingtoolCallId. The table’sCallbackManagerrow is this change seen from the manager: existing handlers and callers keep compiling.
Before and after
The affected type is imported from this module:
import type { DynamicTool } from '@langchain/core/tools';The member as @langchain/core@1.1.27 declared it on DynamicToolInput:
func: (input: string, runManager?: CallbackManagerForToolRun, config?: ToolRunnableConfig) => Promise<ToolOutputT>;And as 1.1.28 declares it:
func: (input: string, runManager?: CallbackManagerForToolRun, config?: ToolRunnableConfig) => Promise<ToolOutputT> | AsyncGenerator<unknown, ToolOutputT>;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. Tool definitions and handlers may need no edit. Review code that reads func. Emendant checks each patch in a copy of your repository at 1.1.28 and withholds patches that fail. Read the patch header to see which checks passed.
Where code calls someTool.func(...) itself, for example in a test, either call someTool.invoke(...), which resolves streaming tools to their final output, or check for an async generator before using the result. If you write handlers and want streamed partial results, implement handleToolEvent.
The scan reports the five names in a type position when they are imported from @langchain/core/tools or @langchain/core/callbacks/manager. A tool made with tool(...) and used with its type inferred is not a finding. 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/core 1.1.28. 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 CallbackManagerlangchain-core-npm-1.1.28-callbacks-manager-callback-manager-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of DynamicStructuredToollangchain-core-npm-1.1.28-tools-dynamic-structured-tool-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of DynamicToollangchain-core-npm-1.1.28-tools-dynamic-tool-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of DynamicStructuredToolInputlangchain-core-npm-1.1.28-tools-dynamic-structured-tool-input-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of DynamicToolInputlangchain-core-npm-1.1.28-tools-dynamic-tool-input-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/core/1.1.28.json, snapshot 2026-09-23.5.
Primary sources
@langchain/core 1.1.30: withStructuredOutput accepts a Standard Schema
@langchain/core@1.1.30 adds Standard Schema support for structured output. withStructuredOutput on every language model gains two overloads that take a SerializableSchema: a schema implementing both Standard Schema V1 and Standard JSON Schema V1. Zod schemas and plain JSON schemas keep working. Code that overrides withStructuredOutput in a subclass, or implements a model’s type by hand, must declare the new overloads.
What changed
withStructuredOutputtakes aSerializableSchema.BaseLanguageModelandBaseChatModeleach add an overload returningRunOutput, and one withincludeRawreturning{ raw: BaseMessage; parsed: RunOutput }. The existing Zod andRecord<string, any>overloads are unchanged.- Every model class inherits them.
SimpleChatModel,BaseLLM,LLMand the fakes in@langchain/core/utils/testingextend one of the two. The feed has a row for each of the nine, so the table lists nine. - The schema type is exported.
@langchain/core/utils/standard_schemaexportsSerializableSchemaand the type guardsisSerializableSchema,isStandardSchemaandisStandardJsonSchema.
Before and after
The affected type is imported from this module:
import type { BaseChatModel } from '@langchain/core/language_models/chat_models';The overload @langchain/core@1.1.30 adds to BaseChatModel, beside those 1.1.29 declared:
withStructuredOutput<RunOutput extends Record<string, any> = Record<string, any>>(outputSchema: SerializableSchema<RunOutput>, config?: StructuredOutputMethodOptions<false>): Runnable<BaseLanguageModelInput, RunOutput>;Migration guidance and its limits
All nine 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 call to withStructuredOutput with a Zod schema still compiles, so most sites may need no edit. Emendant checks each patch in a copy of your repository at 1.1.30 and withholds patches that fail. Read the patch header to see which checks passed.
A subclass that overrides withStructuredOutput must add the two SerializableSchema overloads, importing the type from @langchain/core/utils/standard_schema. A mock typed as one of these classes must accept the new schema shape.
The scan reports the nine names in a type position when they are imported from the modules above. A provider’s chat model class that overrides withStructuredOutput is not a finding, although the compiler checks it. The release also changes MESSAGE_SYMBOL to be declared as symbol rather than unique symbol, which the feed does not describe. A clean scan says no file names these types from those modules, and nothing more about the release.
What Emendant detects, fixes and verifies
9 changes in @langchain/core 1.1.30. 0 automatic fixes, 9 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 BaseLanguageModellangchain-core-npm-1.1.30-language-models-base-base-language-model-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of BaseChatModellangchain-core-npm-1.1.30-language-models-chat-models-base-chat-model-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of SimpleChatModellangchain-core-npm-1.1.30-language-models-chat-models-simple-chat-model-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of BaseLLMlangchain-core-npm-1.1.30-language-models-llms-base-llm-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of LLMlangchain-core-npm-1.1.30-language-models-llms-llm-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of FakeChatModellangchain-core-npm-1.1.30-utils-testing-fake-chat-model-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of FakeLLMlangchain-core-npm-1.1.30-utils-testing-fake-llm-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of FakeStreamingChatModellangchain-core-npm-1.1.30-utils-testing-fake-streaming-chat-model-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of FakeStreamingLLMlangchain-core-npm-1.1.30-utils-testing-fake-streaming-llm-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/core/1.1.30.json, snapshot 2026-09-23.4.
Primary sources
@langchain/core 1.1.31: fakeModel removed from utils/testing
@langchain/core 1.1.31 removes fakeModel, the fluent builder for a fake chat model, from @langchain/core/utils/testing. The function and the file that defined it, fake_model_builder, are both gone between 1.1.30 and 1.1.31: nothing in the package takes its place. A test file importing fakeModel from that subpath fails at the import, before any test runs.
What changed
fakeModelis gone, and nothing replaces it. It built aFakeBuiltModelchat model whose.respond()and.respondWithTools()queued the messages, errors or tool calls a test wanted back on eachinvoke()call. The 1.1.30 declaration files export it from./fake_model_builder; the 1.1.31 files have no such export and no such file. Every other fake in the module (FakeChatModel,FakeListChatModel,FakeLLM,FakeEmbeddings,FakeRetriever,FakeVectorStoreand the rest) is unchanged.
Before and after
A test importing the removed builder:
import { fakeModel } from '@langchain/core/utils/testing';
export { fakeModel };Emendant reports this import, and asks a model for a rewrite only where you name a provider. fakeModel’s queue (.respond(), .respondWithTools(), .alwaysThrow(), .structuredResponse()) has no equivalent among the fakes 1.1.31 still exports, so there is no mechanical rewrite and no drop-in replacement to write one against. Reproducing the same behaviour means composing FakeListChatModel or FakeChatModel by hand, or keeping a local copy of the removed class.
Migration guidance and its limits
Emendant reports imports of the removed builder and supports assisted fixes when you name a model provider. There is no direct replacement in 1.1.31. Review what each test needs, then use the supported fake models or keep a local implementation where the old behaviour is required.
An import of fakeModel from anywhere other than @langchain/core/utils/testing, such as a local alias or a vendored copy of the old builder, is not this finding. Re-exports through another module are outside this coverage.
A clean scan says none of your files import fakeModel from @langchain/core/utils/testing. It says nothing about the rest of 1.1.31, or about any other release between your installed version and this one: this entry covers exactly the one export named above.
What Emendant detects, fixes and verifies
1 change in @langchain/core 1.1.31. 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 |
|---|---|---|---|---|
Removed fakeModellangchain-core-npm-1.1.31-utils-testing-fake-model-removed | Breaking |
| 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/core 1.1.30 was compiled against 1.1.31. A row without one is a change the compiler does not report, such as a deprecation or a change in behaviour.
Requires emendant@0.1.0 or later. Feed entry feed/npm/@langchain/core/1.1.31.json, snapshot 2026-09-20.1.
Primary sources
@langchain/core 1.1.32: DynamicStructuredTool gains a ToolEventT type parameter before NameT
@langchain/core@1.1.32 infers types for tool streams. A tool whose function is an async generator used to be typed as yielding unknown. It now carries a ToolEventT type parameter for what it yields, and tool() infers it from the function it wraps. On DynamicStructuredTool the new parameter is inserted before NameT, so a tool name passed as the fifth type argument now lands in the wrong place.
What changed
DynamicStructuredToolhas a new fifth type parameter. The list was<SchemaT, SchemaOutputT, SchemaInputT, ToolOutputT, NameT>and is now<SchemaT, SchemaOutputT, SchemaInputT, ToolOutputT, ToolEventT, NameT>. A reference that gave a tool name as the fifth argument now gives it asToolEventT, andNameTfalls back tostring. That can still compile, with the name’s literal type lost and the tool typed as yielding the name.DynamicToolgainsToolEventTas its second parameter. It has a default,ToolEventType, which isunknown, so existing references compile.funcyieldsToolEventT. OnDynamicToolInputandDynamicStructuredToolInput,funcreturnedPromise<ToolOutputT> | AsyncGenerator<unknown, ToolOutputT>. It now returnsAsyncGenerator<ToolEventT, ToolOutputT>in the second case. The classes’funcand_callfollow.
Before and after
The affected type is imported from this module:
import type { DynamicStructuredTool } from '@langchain/core/tools';The class head as @langchain/core@1.1.31 declared it:
declare class DynamicStructuredTool<SchemaT = ToolInputSchemaBase, SchemaOutputT = ToolInputSchemaOutputType<SchemaT>, SchemaInputT = ToolInputSchemaInputType<SchemaT>, ToolOutputT = ToolOutputType, NameT extends string = string> extends StructuredTool<SchemaT, SchemaOutputT, SchemaInputT, ToolOutputT> {And as 1.1.32 declares it:
declare class DynamicStructuredTool<SchemaT = ToolInputSchemaBase, SchemaOutputT = ToolInputSchemaOutputType<SchemaT>, SchemaInputT = ToolInputSchemaInputType<SchemaT>, ToolOutputT = ToolOutputType, ToolEventT = ToolEventType, NameT extends string = string> extends StructuredTool<SchemaT, SchemaOutputT, SchemaInputT, ToolOutputT, ToolEventT> {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. A reference with no type arguments, or with four or fewer, still compiles and may need no edit. Emendant checks each patch in a copy of your repository at 1.1.32 and withholds patches that fail. Read the patch header to see which checks passed.
Where code writes DynamicStructuredTool<S, O, I, Out, "name">, insert the event type before the name: DynamicStructuredTool<S, O, I, Out, unknown, "name">, or the type the tool yields. Code that consumed a streaming tool’s events as unknown and narrowed them can now rely on the inferred type.
The scan reports the four names in a type position when they are imported from @langchain/core/tools. A tool made with tool() whose type is inferred is not a finding, although its type now carries the inferred events. A clean scan says no file names these types from that module, and nothing more about the release.
What Emendant detects, fixes and verifies
4 changes in @langchain/core 1.1.32. 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 DynamicStructuredToollangchain-core-npm-1.1.32-tools-dynamic-structured-tool-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of DynamicToollangchain-core-npm-1.1.32-tools-dynamic-tool-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of DynamicStructuredToolInputlangchain-core-npm-1.1.32-tools-dynamic-structured-tool-input-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of DynamicToolInputlangchain-core-npm-1.1.32-tools-dynamic-tool-input-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/core/1.1.32.json, snapshot 2026-09-23.4.
Primary sources
@langchain/core 1.1.35: Zod types replaced by ZodV3Like and ZodV4Like in withStructuredOutput
@langchain/core@1.1.35 stops naming Zod’s own types in its public API. withStructuredOutput and the zodSchema of JsonOutputKeyToolsParserParams now take ZodV3Like or ZodV4Like, which are small structural interfaces, so a project on a different Zod version no longer makes the compiler compare two copies of Zod. Chat models also gain a public getLsParamsWithDefaults method. Code that overrides these methods or implements these types by hand is what can break.
What changed
withStructuredOutputtakes structural schema types. OnBaseLanguageModelandBaseChatModel, the schema parameter wasZodType<RunOutput>fromzod/v3or$ZodType<RunOutput>fromzod/v4/core. It is nowZodV3Like<RunOutput>orZodV4Like<RunOutput>. A real Zod schema still satisfies them.SimpleChatModel,BaseLLM,LLMand the fake models in@langchain/core/utils/testinginherit the change.zodSchemais typed the same way.JsonOutputKeyToolsParserParams.zodSchemamoves fromz3.ZodType<T>andz4.$ZodType<T, T>toZodV3Like<T>andZodV4Like<T, T>.- Chat models require
getLsParamsWithDefaults. It wrapsgetLsParamsand always adds the newls_integrationfield to the LangSmith parameters. It is declared onBaseChatModel, soSimpleChatModel,FakeChatModelandFakeStreamingChatModelcarry it too.
Before and after
The affected type is imported from this module:
import type { JsonOutputKeyToolsParserParams } from '@langchain/core/output_parsers/openai_tools';The member as @langchain/core@1.1.34 declared it:
zodSchema?: z3.ZodType<T>;And as 1.1.35 declares it:
zodSchema?: ZodV3Like<T>;Migration guidance and its limits
All ten 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. Code that passes a Zod schema in still compiles, so most sites may need no edit. Emendant checks each patch in a copy of your repository at 1.1.35 and withholds patches that fail. Read the patch header to see which checks passed.
A subclass that overrides withStructuredOutput must change its parameter types to ZodV3Like and ZodV4Like, which @langchain/core/utils/types exports. A mock or a structural implementation of a chat model must add getLsParamsWithDefaults.
The scan reports the ten names in a type position when they are imported from the modules above. A provider’s chat model class that overrides withStructuredOutput is not a finding, although the compiler checks it against the new signature. A clean scan says no file names these types from those modules, and nothing more about the release.
What Emendant detects, fixes and verifies
10 changes in @langchain/core 1.1.35. 0 automatic fixes, 10 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 BaseLanguageModellangchain-core-npm-1.1.35-language-models-base-base-language-model-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of BaseChatModellangchain-core-npm-1.1.35-language-models-chat-models-base-chat-model-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of SimpleChatModellangchain-core-npm-1.1.35-language-models-chat-models-simple-chat-model-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of BaseLLMlangchain-core-npm-1.1.35-language-models-llms-base-llm-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of LLMlangchain-core-npm-1.1.35-language-models-llms-llm-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of JsonOutputKeyToolsParserParamslangchain-core-npm-1.1.35-output-parsers-openai-tools-json-output-key-tools-parser-params-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of FakeChatModellangchain-core-npm-1.1.35-utils-testing-fake-chat-model-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of FakeLLMlangchain-core-npm-1.1.35-utils-testing-fake-llm-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of FakeStreamingChatModellangchain-core-npm-1.1.35-utils-testing-fake-streaming-chat-model-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of FakeStreamingLLMlangchain-core-npm-1.1.35-utils-testing-fake-streaming-llm-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/core/1.1.35.json, snapshot 2026-09-23.5.
Primary sources
@langchain/core 1.1.38: LanguageModelLike becomes a RunnableInterface
@langchain/core@1.1.38 redefines LanguageModelLike, the type LangChain uses for “anything that behaves like a language model”. It was an alias of the Runnable class and is now an alias of RunnableInterface, the structural interface a model from another copy of the package can also satisfy. Passing a model where a LanguageModelLike is expected keeps compiling. Code that holds a LanguageModelLike and calls a Runnable method on it, such as pipe or withConfig, does not.
What changed
LanguageModelLikeisRunnableInterface<BaseLanguageModelInput, LanguageModelOutput>. In 1.1.37 it wasRunnable<BaseLanguageModelInput, LanguageModelOutput>. The type loses every member the interface does not declare, among thempipe,withConfig,withRetry,withFallbacks,withListeners,asTool,assign,pick,streamEvents,streamLog,getGraphandname.streamnow returns anIterableReadableStreamInterfacerather than anIterableReadableStream.langchain@1.2.39, whose peer range starts at this release, lists “accept cross-version runnable models in createAgent” in its changelog.
Before and after
The affected type is imported from this module:
import type { LanguageModelLike } from '@langchain/core/language_models/base';The alias as @langchain/core@1.1.37 declared it:
type LanguageModelLike = Runnable<BaseLanguageModelInput, LanguageModelOutput>;And as 1.1.38 declares it:
type LanguageModelLike = RunnableInterface<BaseLanguageModelInput, LanguageModelOutput>;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 passes a model in, or only calls invoke, batch or stream, may need no edit. Emendant checks each patch in a copy of your repository at 1.1.38 and withholds patches that fail. Read the patch header to see which checks passed.
Where code takes a LanguageModelLike and chains it, narrow it to a Runnable first, or accept the concrete model class your code actually builds. Where a function of yours returns a LanguageModelLike that callers pipe, change its return type to the concrete class you build.
The scan reports LanguageModelLike in a type position when it is imported from @langchain/core/language_models/base. A model whose type is inferred, and any Runnable method called on it, is not affected and not reported. A clean scan says no file names this type from that module, and nothing more about the release.
What Emendant detects, fixes and verifies
1 change in @langchain/core 1.1.38. 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 LanguageModelLikelangchain-core-npm-1.1.38-language-models-base-language-model-like-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/core/1.1.38.json, snapshot 2026-09-23.4.
Primary sources
@langchain/core 1.1.45: RunnableWithMessageHistory deprecated
@langchain/core 1.1.45 marks RunnableWithMessageHistory as deprecated. The class is still exported from @langchain/core/runnables, its constructor and its methods are unchanged, and code using it keeps working: the only difference between 1.1.44 and 1.1.45 is a @deprecated tag added to its declaration and to the compiled module beside it. Anyone wrapping a chain in it to carry conversation history is affected, and the marker names LangGraph’s built-in persistence as the route out.
What changed
RunnableWithMessageHistoryis deprecated, not removed. Its declaration in@langchain/core/runnablesgains@deprecated Use LangGraph's built-in persistence instead.Nothing else about it moved: it still extendsRunnableBinding, still takesRunnableWithMessageHistoryInputswithgetMessageHistory, and the package’s exports map is identical to the one 1.1.44 shipped. Emendant reports each import of the name from that module, so you can count the call sites before a later major removes it.
Before and after
A chain wrapper built on the deprecated class:
import { RunnableWithMessageHistory } from '@langchain/core/runnables';
export { RunnableWithMessageHistory };Emendant identifies this deprecated import. The replacement the marker points at is LangGraph’s persistence layer, which holds state outside the runnable rather than wrapping it, so the migration changes where history lives and not just which name is imported. That is a decision per chain, not a mechanical rewrite.
The scan checks the import source. RunnableWithMessageHistory imported from a local compatibility module or from a vendored copy of the class is not this finding, and Emendant does not report it.
Migration guidance and its limits
Emendant identifies the deprecated class and supports assisted fixes when you name a model provider. The class still works in this release. Moving history into LangGraph persistence requires a change to your application design, so plan that migration before replacing the class. A patch may not be available for it.
Nothing breaks at this release. A deprecated class that still compiles and still runs buys you the time to move deliberately, and the declaration does not say which release will remove it. Read the scan as an inventory of call sites rather than as a list of failures.
A clean scan is narrower than the release. 1.1.45 also adds @deprecated markers to streamLog and to streamEvents called with version: "v1", and both are methods on Runnable rather than named exports, so this coverage does not carry them. If your code calls either, the scan will not say so. It says nothing about the rest of 1.1.45 either, or about any release between your installed version and this one.
What Emendant detects, fixes and verifies
1 change in @langchain/core 1.1.45. 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 |
|---|---|---|---|---|
Deprecated RunnableWithMessageHistorylangchain-core-npm-1.1.45-runnables-runnable-with-message-history-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.3.0 or later. Feed entry feed/npm/@langchain/core/1.1.45.json, snapshot 2026-09-23.5.
Primary sources
@langchain/core 1.2.0: chat model streamEvents returns a ChatModelStream without a version
@langchain/core@1.2.0 gives chat models their own streamEvents. Called without a version, it returns a ChatModelStream: an async iterable of events that can also be awaited for the final AIMessage, with .text, .toolCalls, .reasoning and .usage sub-streams. The "v1" and "v2" forms still work and are deprecated on chat models, and so is streamV2, which did the same job under another name. Code that subclasses or reimplements a chat model is what can break.
What changed
BaseChatModeloverridesstreamEvents. In 1.1.49 chat models inherited theRunnableoverloads, which all requireversion. 1.2.0 redeclares them onBaseChatModel, each marked deprecated, and addsstreamEvents(input, options?)returningChatModelStream.streamV2is deprecated. Its declaration now says it will be removed in the next major version, in favour ofstreamEvents.- Every chat model inherits the change.
SimpleChatModeland the test doublesFakeChatModel,FakeListChatModel,FakeStreamingChatModelandFakeBuiltModelall extendBaseChatModel. 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 { BaseChatModel } from '@langchain/core/language_models/chat_models';The documentation example for a ChatModelStream in 1.1.49:
const stream = model.streamV2([{ role: "user", content: "Hello" }]);And in 1.2.0:
const stream = model.streamEvents([{ role: "user", content: "Hello" }]);
// Stream textfor await (const token of stream.text) { process.stdout.write(token);}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. A call that passes a version still compiles, so most sites may need no edit. Emendant checks each patch in a copy of your repository at 1.2.0 and withholds patches that fail. Read the patch header to see which checks passed.
A subclass that overrides streamEvents must now match the chat model overloads, including the one with no version. A mock or a structural implementation of BaseChatModel must declare them too. Move streamV2 calls to streamEvents without a version, and plan to move "v1" and "v2" event consumers to the ChatModelStream before the next major version.
The scan reports the six names in a type position when they are imported from the modules above. A streamEvents or streamV2 call on a provider’s chat model class is not a finding, although that class inherits the same change. A clean scan says no file names these types from those modules, and nothing more about the release.
What Emendant detects, fixes and verifies
6 changes in @langchain/core 1.2.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 BaseChatModellangchain-core-npm-1.2.0-language-models-chat-models-base-chat-model-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of SimpleChatModellangchain-core-npm-1.2.0-language-models-chat-models-simple-chat-model-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of FakeBuiltModellangchain-core-npm-1.2.0-testing-fake-built-model-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of FakeChatModellangchain-core-npm-1.2.0-utils-testing-fake-chat-model-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of FakeListChatModellangchain-core-npm-1.2.0-utils-testing-fake-list-chat-model-members-changed | Breaking medium confidence |
| Patch, only when you name a model provider | Your typecheck and tests |
Changed the members of FakeStreamingChatModellangchain-core-npm-1.2.0-utils-testing-fake-streaming-chat-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/core/1.2.0.json, snapshot 2026-09-23.4.
Primary sources
@langchain/core 1.2.18: RunUpdate members changed
@langchain/core@1.2.18 declares the members of RunUpdate differently, and the record lists the address member with another type. The release also adds explicit agent address support to LangChainTracer. You are affected if your code imports RunUpdate from @langchain/core/tracers/tracer_langchain and supplies or reads its members.
What changed
RunUpdatemembers changed. Emendant reports any use ofRunUpdateimported from@langchain/core/tracers/tracer_langchainin a type position. Naming the type does not mean a changed member reaches your code, so each finding needs a look at which members that code supplies or reads.- Address support on the tracer. The changelog says
LangChainTracergains explicit agent address support, and the 1.2.18 declarations add anaddressmember of typeAgentAddresstoLangChainTracerFields. This is the member to look for when you review a finding. - Dependency floor. The changelog says the release requires langsmith >=0.11.0. Check your lockfile if you pin it.
Before and after
The scan matches a type import like this one, in any type position:
import type { RunUpdate } from '@langchain/core/tracers/tracer_langchain';This change has no deterministic rewrite, so there is no automatic before and after for your call sites. The shape change to look for is the new member in the tracer fields. In 1.2.17 the declaration read:
export interface LangChainTracerFields extends BaseCallbackHandlerInput { exampleId?: string; projectName?: string; client?: LangSmithTracingClientInterface;}In 1.2.18 it adds address:
export interface LangChainTracerFields extends BaseCallbackHandlerInput { exampleId?: string; projectName?: string; address?: AgentAddress; client?: LangSmithTracingClientInterface;}The RunUpdate declaration itself still lists events, inputs, trace_id and dotted_order in the published text, so bring your code into line with whatever your installed typings declare.
Migration guidance and its limits
Run emendant scan after upgrading. The one finding is an assisted fix at medium confidence, and nothing in this release is report only. To get a patch you must name a model provider when you run emendant fix. Without one, the finding is reported with its guidance and no patch is produced.
Review each site before applying a patch. Code that only names the type, for example to annotate a parameter, may need no edit. Where code builds or reads a RunUpdate and touches address, align it with what 1.2.18 declares. If the replacement for a member cannot be determined from the release, a patch may not be available, so read the surrounding code yourself. The record marks typecheck and tests as the checks for a patch, so read the patch header to see which ran.
A clean scan only means no file imports RunUpdate from @langchain/core/tracers/tracer_langchain. It says nothing about a type reached through your own re-export, a copy of the interface, or the other patch changes in this release, which this page does not cover. Run your own typecheck and tests after upgrading.
What Emendant detects, fixes and verifies
1 change in @langchain/core 1.2.18. 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 RunUpdatelangchain-core-npm-1.2.18-tracers-tracer-langchain-run-update-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/core/1.2.18.json, snapshot 2026-10-16.3.
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
The LangChain.js migration guide lists every release page and says which to read for your upgrade.