Skip to content

Plugin console.log/warn/error output corrupts TUI display #19108

Closed as not planned

Description

@RaviTharuma

Bug

Plugins loaded via opencode.json "plugin" array run in the same Bun process as OpenCode. When plugins (or their dependencies) call console.log, console.warn, or console.error, the output goes directly to stdout/stderr, corrupting the TUI display.

The logLevel config option only controls OpenCode's own slog-based logging — it has no effect on plugin console output.

Affected plugins (examples)

  • @rehydra/opencode — its dependency rehydra calls console.warn("Validation warnings:", ...) on every anonymization pass (upstream issue)
  • Custom .opencode/plugins/*.js — any plugin using console.log for debugging spams the TUI

Screenshot

Plugin console spam

Raw { c, Validation warnings:, and [memorix] hook fired: lines mixed into the TUI output, making it unreadable.

Expected behavior

Plugin console.* output should either:

  1. Be intercepted and routed through OpenCode's structured Log system (respecting logLevel)
  2. Be suppressed by default with an opt-in pluginLogLevel config
  3. Be redirected to a log file rather than stdout

Root cause

In packages/opencode/src/plugin/index.ts, plugins are loaded via import(plugin) and their init functions are called directly. There's no console interception — plugins share the global console object with the TUI process.

Suggested fix

Wrap plugin initialization and hook execution with a console override that routes through the Log system:

function withPluginConsole<T>(pluginName: string, fn: () => T): T {
  const original = { ...console }
  const pluginLog = Log.create({ service: `plugin:${pluginName}` })
  console.log = (...args) => pluginLog.info(args.map(String).join(" "))
  console.warn = (...args) => pluginLog.warn(args.map(String).join(" "))
  console.error = (...args) => pluginLog.error(args.map(String).join(" "))
  try {
    return fn()
  } finally {
    Object.assign(console, original)
  }
}

This keeps plugin logging visible in OpenCode's log system while preventing stdout corruption.

Environment

  • OpenCode 1.3.0
  • macOS 15.5
  • Bun 1.2.x

Activity

  1. added
    coreAnything pertaining to core functionality of the application (opencode server stuff)
    on Mar 25, 2026
  2. github-actions commented on Mar 25, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

    • Plugin event handler errors corrupt TUI display #12931: Plugin event handler errors corrupt TUI display — same root cause (plugin code writing to stderr/stdout corrupts the TUI display, same file packages/opencode/src/plugin/index.ts), and overlapping proposed fixes (proper logging for plugins). Please review whether your issue is already covered there or if this is a distinct case worth keeping separate.

    If you believe this is a distinct issue, please clarify the difference in a comment.

  3. RaviTharuma commented on Mar 25, 2026

    @RaviTharuma
    Author

    This is related to #12931 but distinct in scope:

    #12931 covers:

    • Plugin event handler errors not being caught (missing await + try-catch)
    • Error output from failing plugins corrupting the TUI
    • Missing log property on PluginInput

    This issue (#19108) covers:

    • console.log/warn/error calls from normal plugin operation (not errors) corrupting the TUI
    • Third-party dependencies of plugins using console.* (e.g. rehydra's anonymizer calling console.warn on every pass)
    • The logLevel config having no effect on plugin console output

    The root cause is the same (plugins share the global console with the TUI process), but the fix in #12931 (adding error handling + log to PluginInput) wouldn't solve this issue — even if plugins themselves use structured logging, their dependencies (npm packages) will still use console.* and corrupt the display.

    The fix in PR #19109 addresses both issues by intercepting console globally before plugins load, routing everything through the Log system. This catches both plugin code and their transitive dependencies.

    Happy to coordinate with @rekram1-node on merging both fixes if needed.

  4. removed
    coreAnything pertaining to core functionality of the application (opencode server stuff)
    on May 3, 2026
  5. github-actions commented on Jul 5, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions