@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
This finding carries an assisted fix. Naming a model provider on the command line or in emendant.json lets fix try it, and without one the finding is reported with its guidance and nothing is sent anywhere. Expect it back unfixed: nothing in 1.1.31 replaces this builder, and the guidance tells the model to decline rather than invent a name. Read each site the scan names and decide what its test needs before you rewrite it.
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. The matcher follows the module a name came from, not the name by itself, so a re-export under a different specifier does not match here.
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 patched by a transform, 1 patched only with a model provider you name, 0 report only. Every patch is proved in a copy of your repository before it is offered, and its header names the checks that passed. This table is generated from the feed entry, so it cannot claim more than the entry does.
| 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.
Coverage
- Snapshot
2026-09-20.1, sequence 27, signed 20 September 2026- Minimum CLI
emendant@0.1.0- Feed entry
feed/npm/@langchain/core/1.1.31.json
emendant feed status shows the snapshot your machine holds, and emendant feed update fetches the latest.
Primary sources
Every claim above was checked against these, each pinned to the release rather than to a default branch.
- @langchain/core@1.1.31npm registry, the published package
- @langchain/core@1.1.30npm registry, the published package
Scan your repository
Runs locally, reads your lockfile and source, sends nothing anywhere.
npx emendant scanThen npx emendant fix writes the patches the table says exist. The getting started guide covers the flags and the patch grades.