Skip to content

Plugin init logs leak to stdout in CLI subcommands (message send, etc.) #51496

@braminatorh

Description

@braminatorh

Problem

When running openclaw message send, plugin initialization logs ([plugins] lines) are printed to stdout instead of stderr. This contaminates any script that captures output via $(...) or pipes.

Evidence

$ openclaw message send --channel whatsapp --target "+31627894125" --message "test" --dry-run >/tmp/stdout.txt 2>/tmp/stderr.txt
$ cat /tmp/stdout.txt
[plugins] graphiti-kg: registered (url: http://127.0.0.1:8000, group: openclaw-main)
[plugins] [email protected]: plugin registered (db: /home/braminator/.openclaw/memory/lancedb-pro, model: text-embedding-3-small)
[plugins] mdMirror: no agent workspaces found, writes will use fallback dir: /home/braminator/.openclaw/workspace/memory-md
[plugins] graphiti-knowledge-graph: loaded without install/load-path provenance; treat as untracked local code and pin trust via plugins.allow or install records (/home/braminator/.openclaw/extensions/graphiti-knowledge-graph/index.ts)
[plugins] memory-lancedb-pro: loaded without install/load-path provenance; treat as untracked local code and pin trust via plugins.allow or install records (/home/braminator/.openclaw/extensions/memory-lancedb-pro/index.ts)
[plugins] graphiti-kg: registered (url: http://127.0.0.1:8000, group: openclaw-main)
[plugins] [email protected]: plugin registered (db: /home/braminator/.openclaw/memory/lancedb-pro, model: text-embedding-3-small)
[plugins] mdMirror: no agent workspaces found, writes will use fallback dir: /home/braminator/.openclaw/workspace/memory-md

The [plugins] lines above all appear on stdout (not stderr), mixed with the actual result.

Impact

Scripts that capture openclaw message send output to check for error conditions get polluted with plugin init noise:

probe=$(openclaw message send ... --dry-run 2>&1)
# $probe now contains [plugins] lines + actual result

Expected Behavior

Plugin initialization logs should go to stderr (or be suppressed entirely when --quiet / not a TTY). Stdout should only contain the actual command result.

Workaround

A filter wrapper is being used locally:

openclaw message send "$@" \
  2> >(grep -v '^\[plugins\]' >&2) \
  | grep -v '^\[plugins\]'

Affected Commands

  • openclaw message send
  • Likely all openclaw subcommands that load plugins

Version

OpenClaw 2026.3.13 (61d171a)

Suggested Fix

In the plugin loader, check if stdout is a TTY or if a --quiet flag is set before emitting [plugins] init messages. Otherwise, route them to stderr unconditionally.

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