TanStack AI version
latest
Framework/Library version
latest
Describe the bug and the steps to reproduce it
Summary
@tanstack/ai-event-client's envelope.js calls crypto.randomUUID() (falling back to Math.random()) at top-level module scope to seed a runtime ID. Cloudflare Workers (and other edge runtimes) forbid random-value generation in global scope, so simply importing @tanstack/ai's chat() crashes the Worker at module-evaluation time.
Error
Error: Disallowed operation called within global scope. Asynchronous I/O
(ex: fetch() or connect()), setting a timeout, and generating random values
are not allowed within global scope. To fix this error, perform this operation
within a handler.
at createRuntimeId (.../assets/tool-definition-*.js)
Offending code
@tanstack/ai-event-client/dist/esm/envelope.js:
function createRuntimeId() {
const cryptoLike = globalThis.crypto;
if (cryptoLike?.randomUUID) {
return cryptoLike.randomUUID();
}
return Math.random().toString(36).slice(2);
}
const runtimeId = (() => {
if (!globalThis.__TANSTACK_AI_DEVTOOLS_RUNTIME_ID__) {
globalThis.__TANSTACK_AI_DEVTOOLS_RUNTIME_ID__ = createRuntimeId(); // runs at import time
}
return globalThis.__TANSTACK_AI_DEVTOOLS_RUNTIME_ID__;
})();
This is pulled in unconditionally by @tanstack/ai (the devtools middleware is always added to the chat middleware chain), so it isn't tree-shakeable:
// @tanstack/ai/dist/esm/activities/chat/index.js
import { devtoolsMiddleware } from "@tanstack/ai-event-client";
// ...
const allMiddleware = [devtoolsMiddleware(), ...config.middleware || [], stripToSpecMiddleware()];
Reproduction
- Use
@tanstack/ai in a Cloudflare Workers project (e.g. TanStack Start + @cloudflare/vite-plugin).
- Import and call
chat() from a server route.
vite build + run the Worker (or prerender) → crash on module evaluation.
Expected behavior
Importing @tanstack/ai should not perform random-value generation at module scope. The runtime ID should be generated lazily (on first event emission / inside a handler), so the module is safe to evaluate in edge/global scope.
Suggested fix
Defer the ID generation to first use rather than computing it eagerly at module load, e.g.:
let _runtimeId;
function getRuntimeId() {
if (!globalThis.__TANSTACK_AI_DEVTOOLS_RUNTIME_ID__) {
globalThis.__TANSTACK_AI_DEVTOOLS_RUNTIME_ID__ = createRuntimeId();
}
return (_runtimeId ??= globalThis.__TANSTACK_AI_DEVTOOLS_RUNTIME_ID__);
}
and call getRuntimeId() from createAIDevtoolsEventEnvelope() / getAIDevtoolsRuntimeId() instead of reading a module-level runtimeId.
Workaround
Pre-seed the global before the module evaluates, via a Worker-build banner:
// vite.config.ts
environments: {
ssr: {
build: {
rollupOptions: {
output: { banner: 'globalThis.__TANSTACK_AI_DEVTOOLS_RUNTIME_ID__ ||= "ssr";' },
},
},
},
}
Environment
@tanstack/ai: 0.23.1
@tanstack/ai-event-client: 0.4.2
@tanstack/react-start: 1.168.18
@cloudflare/vite-plugin: 1.39.0
vite: 8.0.14
- Runtime: Cloudflare Workers (workerd)
### Your Minimal, Reproducible Example - (Sandbox Highly Recommended)
TanStack Start
### Screenshots or Videos (Optional)
_No response_
### Do you intend to try to help solve this bug with your own PR?
None
### Terms & Code of Conduct
- [x] I agree to follow this project's Code of Conduct
- [x] I understand that if my bug cannot be reliable reproduced in a debuggable environment, it will probably not be fixed and this issue may even be closed.
TanStack AI version
latest
Framework/Library version
latest
Describe the bug and the steps to reproduce it
Summary
@tanstack/ai-event-client'senvelope.jscallscrypto.randomUUID()(falling back toMath.random()) at top-level module scope to seed a runtime ID. Cloudflare Workers (and other edge runtimes) forbid random-value generation in global scope, so simply importing@tanstack/ai'schat()crashes the Worker at module-evaluation time.Error
Offending code
@tanstack/ai-event-client/dist/esm/envelope.js:This is pulled in unconditionally by
@tanstack/ai(the devtools middleware is always added to the chat middleware chain), so it isn't tree-shakeable:Reproduction
@tanstack/aiin a Cloudflare Workers project (e.g. TanStack Start +@cloudflare/vite-plugin).chat()from a server route.vite build+ run the Worker (or prerender) → crash on module evaluation.Expected behavior
Importing
@tanstack/aishould not perform random-value generation at module scope. The runtime ID should be generated lazily (on first event emission / inside a handler), so the module is safe to evaluate in edge/global scope.Suggested fix
Defer the ID generation to first use rather than computing it eagerly at module load, e.g.:
and call
getRuntimeId()fromcreateAIDevtoolsEventEnvelope()/getAIDevtoolsRuntimeId()instead of reading a module-levelruntimeId.Workaround
Pre-seed the global before the module evaluates, via a Worker-build banner:
Environment
@tanstack/ai:0.23.1@tanstack/ai-event-client:0.4.2@tanstack/react-start:1.168.18@cloudflare/vite-plugin:1.39.0vite:8.0.14