Skip to content

[BUG] Cyclic symlinks in global skills cause blank TUI and unbounded memory growth #42216

Closed as not planned

Description

@YoungSens

Description

A cyclic directory symlink inside a global skill causes OpenCode to remain on a completely blank TUI while skill discovery recursively follows the loop.

On macOS, the process stayed alive, logs stopped at message=init, and memory grew to approximately 7.3 GB. Sampling showed a Bun worker repeatedly performing openat calls.

Moving the cyclic symlinks out of ~/.agents/skills fixed the issue immediately. With the same OpenCode binary and project, skill initialization then completed in about one second and the TUI rendered normally.

This appears to be a more severe form of #27027. That report covers large symlink targets and slow startup; this case uses an actual symlink cycle and results in effectively unbounded traversal and memory growth. #27072 has a similar blank-TUI symptom but concerns project file scanning rather than skill discovery.

Expected behavior

OpenCode should detect an already visited directory by real path or filesystem identity, skip the cyclic edge, emit a warning containing the offending path, and continue rendering the TUI.

Actual behavior

  • TUI remains completely blank
  • logs stop at message=init
  • the process continuously traverses files
  • memory usage keeps growing
  • no actionable error identifies the cyclic skill path

Diagnostic result

Following the affected skill tree reproduced recursive path expansion. After removing 16 nested symlinks that formed self and cross-directory cycles, the followed traversal contained only 177 entries and OpenCode logged init count=10 before rendering the full welcome screen.

Plugins

None

OpenCode version

1.18.16, installed with Homebrew

Steps to reproduce

Warning: this can cause rapid memory growth. Run only in a disposable HOME and stop the process promptly.

TEST_HOME=$(mktemp -d)
mkdir -p "$TEST_HOME/.agents/skills/loop-skill"

cat > "$TEST_HOME/.agents/skills/loop-skill/SKILL.md" <<EOF
---
name: loop-skill
description: Reproduce cyclic skill symlink scanning
---
EOF

ln -s "$TEST_HOME/.agents/skills/loop-skill" \
  "$TEST_HOME/.agents/skills/loop-skill/self"

HOME="$TEST_HOME" opencode

The TUI remains blank while the process recursively follows self.

Remove the cyclic link and rerun:

unlink "$TEST_HOME/.agents/skills/loop-skill/self"
HOME="$TEST_HOME" opencode

The TUI renders normally.

Screenshot and/or share link

No screenshot. The blank screen contains no diagnostic text.

Operating System

macOS 26.5.2, Apple Silicon arm64

Terminal

iTerm2 3.6.11, also reproduced in an isolated PTY

Activity

  1. github-actions commented on Aug 13, 2026

    @github-actions
    Contributor

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

    These reports describe the same underlying bug: skill discovery with followSymlinks: true and no cycle detection. Your report adds useful detail (memory growth to 7.3 GB, minimal reproduction script), so it may be worth linking rather than closing — but please check whether the existing issues already cover your case.

  2. YoungSens commented on Aug 13, 2026

    @YoungSens
    Author

    Additional detail about the real-world trigger:

    The cycle was introduced by the installed layout of two skills, find-skills and web-design-guidelines. Each of those skill directories contained symlinks to the top-level installed skills, including links back to itself and to the other skill.

    The relevant topology was equivalent to:

    ~/.agents/skills/find-skills/find-skills
      -> ~/.agents/skills/find-skills
    
    ~/.agents/skills/find-skills/web-design-guidelines
      -> ~/.agents/skills/web-design-guidelines
    
    ~/.agents/skills/web-design-guidelines/find-skills
      -> ~/.claude/skills/find-skills
      -> ~/.agents/skills/find-skills
    
    ~/.agents/skills/web-design-guidelines/web-design-guidelines
      -> ~/.claude/skills/web-design-guidelines
      -> ~/.agents/skills/web-design-guidelines
    

    So this was not merely a symlink to a large external tree: the way these installed skills referenced the shared top-level skill set created both direct self-loops and cross-skill loops. OpenCode followed those links during global skill discovery.

    After moving only the 16 nested symlinks out of these two directories, while leaving both SKILL.md files intact, startup returned to normal.

  3. thdxr commented on Oct 11, 2026

    @thdxr
    Member

    Thanks for the report! OpenCode 2.0 is now out and development is focused on V2, so we're closing issues filed against OpenCode 1. Please upgrade (opencode upgrade --major, details: https://anoma.ly/notes/opencode-2-0), and if this is still relevant on 2.0, reopen this issue or open a new one with your 2.0 version.

    — from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊

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