Skip to content

Permission service logs full ruleset on every tool call, causing 50GB+ log bloat #17218

@XucroYuri

Description

@XucroYuri

Permission service logs full ruleset on every tool call, causing 50GB+ log bloat

Bug Summary

The service=permission logger writes the entire permission ruleset (all rules, including every external_directory allow/ask entry) into every single log line at INFO level. With a moderate number of installed skills (~648), each permission log line balloons to ~148KB (148,601 characters). During an active session with Oh-My-OpenCode subagents, this produces ~29MB/min of logs per process, causing the log directory to grow to 50GB+ within hours.

Environment

Component Version/Value
OpenCode 1.1.53
OS macOS (darwin-arm64)
Plugin oh-my-opencode@3.9.0
Installed Skills 648 (via ~/.agents/skills/ + ~/.claude/skills/)
MCP Servers 18 configured (shadcn, context7, grep, github, playwright, filesystem, memory, sequential-thinking, fetch, git, postgres, sqlite, redis, mongodb, cloudflare, supabase, neon, zai-mcp-server)

Reproduction

Prerequisites

  • Install 100+ skills (via ~/.agents/skills/ or ~/.claude/skills/)
  • Configure multiple MCP servers
  • Optionally install oh-my-opencode plugin (amplifies the issue via subagent processes)

Steps

  1. Start OpenCode: opencode
  2. Send any message that triggers tool calls (e.g., "list files in current directory")
  3. Observe ~/.local/share/opencode/log/ directory growth

Expected

Log directory grows at a reasonable rate (~1-10MB per session).

Actual

Log directory grows at ~29MB/min per active process. With oh-my-opencode spawning multiple subagent processes, total growth reaches hundreds of MB per minute.

Root Cause Analysis

Primary: Permission ruleset serialized into every log line

Every tool invocation triggers permission evaluation, which logs two lines to the session log:

Line 1 — Permission check (contains full ruleset):

INFO  2026-03-12T17:43:54 +1ms service=permission permission=bash pattern=echo "hello" ruleset=[{"permission":"*","pattern":"*","action":"allow"},{"permission":"doom_loop","pattern":"*","action":"ask"},{"permission":"external_directory","pattern":"*","action":"ask"},{"permission":"external_directory","pattern":"/Users/xuyu/.local/share/opencode/tool-output/*","action":"allow"},{"permission":"external_directory","pattern":"/Users/xuyu/.claude/skills/postgresql-code-review/*","action":"allow"},{"permission":"external_directory","pattern":"/Users/xuyu/.claude/skills/python-packaging/*","action":"allow"}, ... <1,278 rules total> ...]

Line 2 — Evaluation result (also contains full ruleset):

INFO  2026-03-12T17:43:54 +1ms service=permission permission=bash pattern=echo "hello" action={"permission":"*","pattern":"*","action":"allow"} evaluated

Each skill contributes ~2 external_directory rules. With 648 skills:

  • 1,278 rules serialized per permission check
  • Each rule ~116 characters
  • Total ruleset string: ~148KB per log line

Quantified Impact

Metric Value
Rules per permission check 1,278
Characters per permission log line 148,601
Log lines per tool call 2 (check + evaluate)
Bytes per tool call ~296KB
Tool calls per minute (active session) ~100+
Log growth per minute (single process) ~29MB
Log growth per minute (11 processes) ~320MB
Log growth per hour (worst case) ~19GB

Evidence from real session

# Log file: only 200K lines but 24GB
$ wc -l 2026-03-12T165514.log
200047       # → avg 120KB per line!

# Active log: 7066 lines, 52% are permission checks
Total lines:      7,066
Permission lines: 3,709 (52.5%)
Bus publishing:     640
Message.part:       557

# Permission checks by tool type:
3200 permission=skill      # skills loaded on every message
 428 permission=bash       # shell commands
 119 permission=task       # subagent delegation

# Single permission line size:
$ grep -m1 'service=permission' log | wc -c
148601

Secondary: Orphaned subagent processes

Oh-My-OpenCode spawns subagent processes (Sisyphus, Hephaestus, explore, librarian, etc.) that sometimes become orphaned (ppid=1) and continue running for 16+ hours, each maintaining their own log session:

# 10 orphaned processes found, all ppid=1
 8697     1  Thu Mar/12 09:36:41 2026   opencode  # 16 hours old!
 8849     1  Thu Mar/12 09:36:49 2026   opencode
 8991     1  Thu Mar/12 09:36:53 2026   opencode
 9131     1  Thu Mar/12 09:36:59 2026   opencode
 9135     1  Thu Mar/12 09:37:02 2026   opencode
10925     1  Thu Mar/12 09:43:07 2026   opencode
34325     1  Thu Mar/12 22:27:23 2026   opencode
80965     1  Thu Mar/12 23:00:09 2026   opencode
85117     1  Fri Mar/13 00:08:42 2026   opencode
86339     1  Fri Mar/13 00:55:13 2026   opencode

Tertiary: MCP "Method not found" error spam

Multiple MCP servers repeatedly log -32601: Method not found errors for prompts/list, adding noise:

ERROR service=mcp clientName=filesystem error=MCP error -32601: Method not found failed to get prompts
ERROR service=mcp clientName=sequential-thinking error=MCP error -32601: Method not found failed to get prompts
ERROR service=mcp clientName=mongodb error=MCP error -32601: Method not found failed to get prompts
ERROR service=mcp clientName=playwright error=MCP error -32601: Method not found failed to get prompts
ERROR service=mcp clientName=shadcn error=MCP error -32601: Method not found failed to get prompts

Tertiary: No log rotation or size limits

OpenCode has no built-in log rotation, maximum file size, or auto-cleanup mechanism. A single session log file can grow unboundedly.

Proposed Fixes

P0 — Critical (permission ruleset logging)

  1. Do NOT serialize the full ruleset into log lines. The ruleset=[...] field in permission logs is the single biggest contributor. Options:

    • Remove ruleset from INFO-level logs entirely (move to DEBUG/TRACE)
    • Log only the matched rule, not the entire ruleset
    • Log a ruleset hash/fingerprint instead of the full array
  2. Add a logLevel configuration option that users can set in opencode.json:

    { "logLevel": "warn" }

P1 — High (log management)

  1. Implement log rotation: Max file size (e.g., 100MB per file) with automatic rotation and retention limit (e.g., keep last 5 files or 500MB total).

  2. Auto-cleanup old logs: Delete log files older than N days (configurable, default 7 days).

P2 — Medium (subagent lifecycle)

  1. Ensure subagent processes terminate when parent session ends. Currently orphaned processes (ppid=1) accumulate and continue writing logs indefinitely. (This may be an oh-my-opencode plugin issue rather than core OpenCode.)

P3 — Low (MCP error noise)

  1. Suppress or rate-limit repeated MCP errors: The -32601: Method not found for prompts/list is expected for MCP servers that don't implement the prompts capability. Log once per server at WARN, not repeatedly at ERROR.

Workarounds

Until fixed, users can mitigate with:

# 1. Kill orphaned opencode processes
ps aux | grep opencode | grep -v grep | awk '{print $2}' | xargs kill

# 2. Delete large log files
find ~/.local/share/opencode/log -type f -size +500M -delete

# 3. Set up auto-cleanup cron (daily at 4:00 AM)
(crontab -l 2>/dev/null; echo "0 4 * * * find ~/.local/share/opencode/log -type f -mtime +3 -delete") | crontab -
(crontab -l 2>/dev/null; echo "30 4 * * * find ~/.local/share/opencode/log -type f -size +500M -delete") | crontab -

# 4. Reduce installed skills to decrease ruleset size
# Each skill removed saves ~232 bytes per log line (2 rules × 116 chars)

Impact

  • Disk exhaustion: 50GB+ log accumulation in hours on a 228GB disk
  • Performance degradation: 11 orphaned processes consuming CPU/memory
  • Silent failure: No warnings when logs consume excessive disk space
  • Scales with skill count: More skills installed → exponentially worse logging overhead

Related

  • Potentially related to log cleanup reverse-deletion bugs (where old logs are kept and new logs deleted)
  • Oh-My-OpenCode subagent process lifecycle management
  • MCP server capability negotiation (prompts/list on non-supporting servers)

Metadata

Metadata

Assignees

Labels

coreAnything pertaining to core functionality of the application (opencode server stuff)perfIndicates a performance issue or need for optimization

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