bug: --log-level CLI flag not passed to Worker, file logs always INFO #9086

Open
opened 2026-02-16 18:11:36 -05:00 by yindo · 0 comments
Owner

Originally created by @cuipengfei on GitHub (Feb 11, 2026).

Originally assigned to: @rekram1-node on GitHub.

Description

--log-level ERROR only affects the main thread (TUI). The Worker thread (which writes the log file) hardcodes level: "INFO", causing log files to grow to 120MB+ in long sessions regardless of the CLI flag.

Root Cause

worker.ts ignores the --log-level CLI argument:

// packages/opencode/src/cli/cmd/tui/worker.ts
await Log.init({
  print: process.argv.includes("--print-logs"),
  dev: Installation.isLocal(),
  level: (() => {
    if (Installation.isLocal()) return "DEBUG"
    return "INFO"  // ← Always INFO, ignores --log-level
  })(),
})

Compare with index.ts (main thread), which correctly reads the CLI flag:

// packages/opencode/src/index.ts
await Log.init({
  level: (() => {
    if (opts.logLevel) return opts.logLevel as Log.Level  // ← reads CLI arg
    if (Installation.isLocal()) return "DEBUG"
    return "INFO"
  })(),
})

The Worker is created in thread.ts with only env passed — no CLI args:

const worker = new Worker(workerPath, {
  env: Object.fromEntries(
    Object.entries(process.env).filter(...)
  ),
  // No argv forwarding
})

Additionally, config.logLevel is defined in the schema (config.ts:1009) but never read by either Log.init call, making it effectively dead code.

Impact

  • Log files grow to 100MB+ in long sessions (88K lines, 120MB observed)
  • message.part.updated events alone account for 43% of log lines (one per streaming token)
  • LLM error logs dump full requestBodyValues (350KB+ per line)
  • --log-level ERROR gives users false confidence the issue is resolved

Suggested Fix

Pass log level from main thread to Worker via env variable:

thread.ts:

const worker = new Worker(workerPath, {
  env: {
    ...Object.fromEntries(
      Object.entries(process.env).filter((entry): entry is [string, string] => entry !== undefined),
    ),
    OPENCODE_LOG_LEVEL: opts.logLevel || "",
  },
})

worker.ts:

await Log.init({
  print: process.argv.includes("--print-logs"),
  dev: Installation.isLocal(),
  level: (() => {
    if (process.env.OPENCODE_LOG_LEVEL) return process.env.OPENCODE_LOG_LEVEL as Log.Level
    if (Installation.isLocal()) return "DEBUG"
    return "INFO"
  })(),
})

Also consider reading config.logLevel in both init sites so the config file setting actually works.

Environment

  • OpenCode version: 1.1.56
  • OS: Linux (WSL2)
  • Terminal: Zellij

Steps to Reproduce

  1. opencode --log-level ERROR
  2. Use it for a few minutes (send a message, let agent respond)
  3. Check ~/.local/share/opencode/log/*.log
  4. File is full of INFO-level entries

Related Issues

  • #5004 - Excessive Informational Logging (same symptom, root cause not identified)
  • #6583 - --log-level DEBUG removes log file
  • #8639 - Background logs printed to TUI
Originally created by @cuipengfei on GitHub (Feb 11, 2026). Originally assigned to: @rekram1-node on GitHub. ## Description `--log-level ERROR` only affects the main thread (TUI). The Worker thread (which writes the log **file**) hardcodes `level: "INFO"`, causing log files to grow to **120MB+** in long sessions regardless of the CLI flag. ## Root Cause **`worker.ts`** ignores the `--log-level` CLI argument: ```typescript // packages/opencode/src/cli/cmd/tui/worker.ts await Log.init({ print: process.argv.includes("--print-logs"), dev: Installation.isLocal(), level: (() => { if (Installation.isLocal()) return "DEBUG" return "INFO" // ← Always INFO, ignores --log-level })(), }) ``` Compare with **`index.ts`** (main thread), which correctly reads the CLI flag: ```typescript // packages/opencode/src/index.ts await Log.init({ level: (() => { if (opts.logLevel) return opts.logLevel as Log.Level // ← reads CLI arg if (Installation.isLocal()) return "DEBUG" return "INFO" })(), }) ``` The Worker is created in `thread.ts` with only `env` passed — no CLI args: ```typescript const worker = new Worker(workerPath, { env: Object.fromEntries( Object.entries(process.env).filter(...) ), // No argv forwarding }) ``` Additionally, `config.logLevel` is defined in the schema (`config.ts:1009`) but never read by either `Log.init` call, making it effectively dead code. ## Impact - Log files grow to **100MB+** in long sessions (88K lines, 120MB observed) - `message.part.updated` events alone account for 43% of log lines (one per streaming token) - LLM error logs dump full `requestBodyValues` (350KB+ per line) - `--log-level ERROR` gives users false confidence the issue is resolved ## Suggested Fix Pass log level from main thread to Worker via env variable: **`thread.ts`:** ```typescript const worker = new Worker(workerPath, { env: { ...Object.fromEntries( Object.entries(process.env).filter((entry): entry is [string, string] => entry !== undefined), ), OPENCODE_LOG_LEVEL: opts.logLevel || "", }, }) ``` **`worker.ts`:** ```typescript await Log.init({ print: process.argv.includes("--print-logs"), dev: Installation.isLocal(), level: (() => { if (process.env.OPENCODE_LOG_LEVEL) return process.env.OPENCODE_LOG_LEVEL as Log.Level if (Installation.isLocal()) return "DEBUG" return "INFO" })(), }) ``` Also consider reading `config.logLevel` in both init sites so the config file setting actually works. ## Environment - OpenCode version: 1.1.56 - OS: Linux (WSL2) - Terminal: Zellij ## Steps to Reproduce 1. `opencode --log-level ERROR` 2. Use it for a few minutes (send a message, let agent respond) 3. Check `~/.local/share/opencode/log/*.log` 4. File is full of INFO-level entries ## Related Issues - #5004 - Excessive Informational Logging (same symptom, root cause not identified) - #6583 - --log-level DEBUG removes log file - #8639 - Background logs printed to TUI
yindo added the perf label 2026-02-16 18:11:36 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#9086