Summary
With the default logger (debug: true, or any DebugConfig without a custom logger), the per-category headlines print but the meta payloads do not when chat() runs on Cloudflare Workers / workerd (wrangler dev, Miniflare, TanStack Start on Workers).
You get:
📤 [tanstack-ai:request] activity=chat provider=openrouter model=… messages=1 tools=1 stream=true
📨 [tanstack-ai:output] type=RUN_ERROR
…but never the request body, the chunk contents, or the RUN_ERROR payload (provider / code / upstream message). Debug mode is effectively "headers only" on Workers.
Cause
ConsoleLogger renders meta with console.dir using Node util.inspect options:
// src/logger/console-logger.ts
debug(message, meta) {
console.debug(message);
if (meta !== undefined) console.dir(meta, { depth: null, colors: true });
}
depth / colors are Node-only. workerd's console.dir ignores them and doesn't surface the object to the terminal, so the payload is dropped. The headline survives because it's emitted separately via console.debug(message). (info / warn / error have the same shape.)
This matters because TanStack Start deploys to Cloudflare Workers as a first-class target, so chat() commonly runs under workerd.
Reproduction
- A TanStack Start app running on Cloudflare Workers (
wrangler dev / Miniflare).
chat({ adapter, messages, debug: true }).
- Trigger any request (a failing one is clearest —
RUN_ERROR).
- Terminal shows the
[tanstack-ai:*] headlines but none of the meta objects.
Under Node, console.dir with these options renders the same payloads fine — the gap is workerd-specific.
Suggested fix
Render meta portably — keep the rich console.dir on Node, fall back to a (circular-safe) stringified form elsewhere:
debug(message, meta) {
console.debug(message);
if (meta === undefined) return;
const isNode = typeof process !== 'undefined' && !!process.versions?.node;
if (isNode) console.dir(meta, { depth: null, colors: true });
else console.debug(safeJsonStringify(meta)); // depth-null JSON, no colors
}
(Repeat for info / warn / error. safeJsonStringify should guard against circular references, which the event/chunk objects can contain.)
Workaround (for reference)
Passing a custom debug: { logger } whose methods stringify meta through console.log works today on workerd — so this is purely about making the default logger usable on Workers.
Version
@tanstack/ai@0.26.1
Summary
With the default logger (
debug: true, or anyDebugConfigwithout a customlogger), the per-category headlines print but themetapayloads do not whenchat()runs on Cloudflare Workers / workerd (wrangler dev, Miniflare, TanStack Start on Workers).You get:
…but never the request body, the chunk contents, or the
RUN_ERRORpayload (provider / code / upstream message). Debug mode is effectively "headers only" on Workers.Cause
ConsoleLoggerrendersmetawithconsole.dirusing Nodeutil.inspectoptions:depth/colorsare Node-only. workerd'sconsole.dirignores them and doesn't surface the object to the terminal, so the payload is dropped. The headline survives because it's emitted separately viaconsole.debug(message). (info/warn/errorhave the same shape.)This matters because TanStack Start deploys to Cloudflare Workers as a first-class target, so
chat()commonly runs under workerd.Reproduction
wrangler dev/ Miniflare).chat({ adapter, messages, debug: true }).RUN_ERROR).[tanstack-ai:*]headlines but none of themetaobjects.Under Node,
console.dirwith these options renders the same payloads fine — the gap is workerd-specific.Suggested fix
Render
metaportably — keep the richconsole.diron Node, fall back to a (circular-safe) stringified form elsewhere:(Repeat for
info/warn/error.safeJsonStringifyshould guard against circular references, which the event/chunk objects can contain.)Workaround (for reference)
Passing a custom
debug: { logger }whose methods stringifymetathroughconsole.logworks today on workerd — so this is purely about making the default logger usable on Workers.Version
@tanstack/ai@0.26.1