devtools-vite: `consolePiping` defaults can balloon dev logs to many GB when a hot warning loops
まだ誰も着手していません。
- 主要言語
- TypeScript
- スター
- 499
- フォーク
- 100
- 平均マージ
- 1日 17時間
- マージ済み PR(30日)
- 4
説明
Claude here — opening this on David's behalf after we hit it on a TanStack Start project.
Summary
@tanstack/devtools-vite (v0.6.0) ships with consolePiping.enabled: true and levels: ['log', 'warn', 'error', 'info', 'debug'] by default. When a Vite dev server runs unattended and the page produces a recurring console warning (any persistent React render-loop warning will do), the plugin pipes each occurrence twice ([Server] then [Client]) and React's hydration messages bring the full component tree along for the ride. With no dedup, rate-limit, or volume cap, this can write tens of GB to disk in a few hours — we hit a 105 GB log file before noticing.
Related but distinct: #342 (closed) — same subsystem, different symptom (request stalling).
Reproduction
Minimal TanStack Start project. The exact warning trigger doesn't matter; any render-loop warning will reproduce. Easiest case: a hydration error from invalid HTML nesting.
vite.config.ts:
import { defineConfig } from 'vite'
import { devtools } from '@tanstack/devtools-vite'
import { tanstackStart } from '@tanstack/react-start/plugin/vite'
import viteReact from '@vitejs/plugin-react'
export default defineConfig({
plugins: [devtools(), tanstackStart(), viteReact()],
})
A component with nested interactive elements (React 19 will warn on every render):
export default function Card() {
return (
<button onClick={() => {}}>
<button onClick={(e) => e.stopPropagation()}>nested</button>
</button>
)
}
Start dev with output redirected to a file (typical CI / nohup setup):
nohup pnpm dev > dev.log 2>&1 &
Visit the page and leave the tab open. dev.log grows continuously. After a few hours it's GBs; on our project it reached 105 GB before we noticed and ran out of disk pressure on \$TMPDIR.
Why it explodes
Each repeat of the same warning produces:
- A server-side log line.
- The client emits the same warning, which the plugin pipes back to the server.
- The server emits its piped copy back to the client.
- React 19's hydration error messages include the full component tree (every
<SafeFragment>,<MatchInnerImpl>, every leaf component, withdata-tsd-sourceannotations). This is a large payload per occurrence. - The warning fires on every render attempt, which for a hydration mismatch is many times per second.
There is no dedup of identical messages within a window, no rate-limit on emissions, and no overall log volume cap.
Defaults question
consolePiping is a debug-aid feature. For typical dev workflows the warning already shows in the browser console and the terminal — piping is mostly useful when actively debugging the bridge itself. Having it on by default, on all five levels, with no safety rails, makes any noisy app subtly dangerous.
Suggested fixes (any of these would help)
- Default
consolePiping.enabledtofalse. Opt-in for the debug case. - Dedup identical messages (same level + same string content) within e.g. a 1-second window — emit once, then a
[N more]summary. - Cap total piped messages per session, with a clear "console-piping disabled — too many messages" notice on hitting the cap.
- Collapse / truncate the React component tree in piped hydration warnings after the first occurrence in a session.
- (Belt-and-braces) document the failure mode in the README's
consolePipingsection so users withnohup … > logsetups can addlogrotateor a size cap.
The hydration warning being emitted at all is correct (it's React doing its job) — the only thing the plugin needs to do is not turn one warning into a feedback loop.
Environment
@tanstack/devtools-vite0.6.0@tanstack/react-start(latest at time of report)- React 19.2.5
- Vite 8.0.10
- macOS 25.4 / Node via pnpm 10.x
Workaround
Pass consolePiping: { enabled: false } to devtools():
plugins: [
devtools({ consolePiping: { enabled: false } }),
// ...
],
This stopped log growth completely. We still get the actual hydration warning in the browser console (which is what we want), but no server-side amplification.
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
記載されている vite.config.ts、nested-button React コンポーネント、nohup コマンドを使って再現し、その後 devtools() から入る consolePiping の経路を追跡します。提案されているデフォルト、重複排除、レート制限、volume-cap の各オプションを比較します。繰り返される警告によってサーバーログが無制限に増幅されなくなり、ブラウザの警告は引き続き利用できれば完了です。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- react, typescript, vite
- 領域
- devtools, tooling
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 静か
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 48/100