Skip to content

Debug logging: meta payloads dropped on Cloudflare Workers / workerd (ConsoleLogger uses Node-only console.dir) #730

@tombeckenham

Description

@tombeckenham

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

  1. A TanStack Start app running on Cloudflare Workers (wrangler dev / Miniflare).
  2. chat({ adapter, messages, debug: true }).
  3. Trigger any request (a failing one is clearest — RUN_ERROR).
  4. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions