Skip to content

Fixing "streamText is not a function" After an AI SDK Upgrade

9 min read · updated August 11, 2026

TypeError: streamText is not a function, or its bundled form with a webpack module prefix in front of the name, means the import resolved to a real module and that module has no such export. That is a narrower statement than it looks, and it rules out most of what people try first.

The error, and what it rules out

The two spellings you will see:

TypeError: streamText is not a function
TypeError: (0 , ai__WEBPACK_IMPORTED_MODULE_0__.streamText) is not a function

Both say the same thing. The second is the bundled form and is strictly more informative, because it names the module the binding came from — ai in that example. If the prefix names a different package, the answer is already in the message.

What this is not: it is not a typo, because a missing binding from an ES module import is usually a build-time error rather than a runtime TypeError. It is not a missing package, because that fails at resolution with Cannot find module. And it is not an API key or a network problem, because nothing has been called yet. Something is installed under the name you imported, and it is not the thing you think.

The five causes, in order of likelihood

  • The installed ai predates the export. streamText arrived with AI SDK Core in the 3.1 release. On anything in the 2.x line the package exports the older stream adapters and no streamText at all. This is the single most common cause and it usually means a lockfile that was not updated, or a deployment that installed from a stale lock.
  • You imported from the wrong package. streamText lives in ai. It is not exported by @ai-sdk/react, which has the UI hooks, nor by @ai-sdk/openai, which has the provider. An editor auto-import that picked a neighbouring package produces exactly this error.
  • Two copies of ai in the tree. A monorepo where one workspace depends on the current version and a shared package still depends on an old one gives you a resolution that depends on which file is importing. The code compiles, one route works, another does not.
  • CommonJS interop. const { streamText } = require("ai") in a file that is being treated as CommonJS can hand you the module namespace wrapper rather than the named exports, so the property is genuinely undefined at runtime.
  • A stale build cache. Less common, and worth ruling out before the harder theories, because it costs one command: a framework build directory holding a compiled copy of the old module will keep serving it after the upgrade.

The checks that distinguish them

Ask the installed package directly rather than reasoning about the manifest. This prints the exports of whatever ai actually resolves to from your project root:

node -e "console.log(Object.keys(require('ai')).sort().join(' '))"

If streamText is absent from that list, it is a version problem. If it is present, it is a resolution problem — the file that throws is not getting the same copy.

npm ls ai                  # every path that depends on it, and each version
cat node_modules/ai/package.json | grep '"version"'
npm why ai                 # who is pulling in the copy you did not want

npm ls ai is the one that settles the duplicate case. A single entry means one copy; a tree with the same package listed at two versions, or listed under a nested node_modules, is the third cause. The pnpm and yarn equivalents are pnpm why ai and yarn why ai.

One more check for the second cause, which is the one people misdiagnose most: look at the import line rather than the call. In a bundled stack trace the module prefix names the package; in source, an import of streamText from anything other than ai is the bug regardless of what else is true.

The fix for each

  1. Delete the build cache and reinstall before anything else, because it is fast and it removes a variable: rm -rf .next node_modules, then install. If the error survives that, it is real.
  2. Run the Object.keys command above. Absent export means upgrade: move ai to a version in the 3.1 line or later, and move every @ai-sdk/* package in the same operation so the provider packages and the core package agree.
  3. Present export means fix the import path. streamText, generateText, streamObject and generateObject come from ai; hooks come from the framework package; models come from the provider package.
  4. For a duplicate, resolve to one version. Raise the old dependency’s range, or use your package manager’s override mechanism to force a single copy, then re-run npm ls ai and confirm one entry.
  5. For the CommonJS case, make the importing file an ES module — a .mjs extension or "type": "module" in the nearest package.json — and use a static import rather than require.

Two neighbouring errors have the same diagnosis and are worth recognising, because arriving at this page with one of them and following the version fix will not help. openai is not a function means the provider package, not the core package, is the mismatched one — the default export became callable at a particular version, and an older copy exports a class instead. And The requested module 'ai' does not provide an export named 'streamText' is the same underlying condition surfaced at link time rather than call time, which is what you get in a strict ES module context instead of a bundled one. Both are answered by the same two questions: which version, and which copy.

Keeping it from recurring

The underlying condition is that ai and the @ai-sdk/* packages are versioned together in practice and separately in your manifest. A provider package built against one major and a core package at another can install cleanly and fail at the first call, and the error you get will name a missing function rather than a version conflict.

Three habits make it rare. Upgrade the whole family in one commit and never individually. Keep the lockfile authoritative — a deploy that runs a plain install rather than a lockfile-respecting one can resolve differently from your laptop, which is how “works locally, fails in CI” versions of this error happen. And add one test that imports the module and asserts the functions it needs are functions; it is three lines, it runs in milliseconds, and it converts a runtime failure in a request handler into a build failure. The same argument applies to what an SDK upgrade does to output, which is the other half of the problem and much harder to see.

The version in which each export appeared is the state at the time of writing, and this SDK has shipped several majors. The durable part of this page is the method: ask the installed package what it exports, then ask the resolver which copy the failing file gets.