Bug Description
On Bun runtime, opencode crashes with ENAMETOOLONG error during skill scanning when external skill directories (e.g. ~/.claude/skills/, ~/.agents/skills/) contain circular or broken symlinks.
Root Cause
The skill discovery system uses glob with follow: true to scan external skill directories. When circular symlinks exist (e.g., skills/finishing-a-development-branch/finishing-a-development-branch → points to itself), glob enters an infinite recursion. On Bun runtime, this causes path strings to exceed PATH_MAX, triggering ENAMETOOLONG from readdir which crashes the process. Node.js handles this gracefully, but Bun does not.
Additionally, broken symlinks (target deleted) cause unnecessary I/O errors during scanning.
Reproduction
- Install a Claude Code plugin that creates skill symlinks (e.g., omc)
- Some skills may leave behind circular or broken symlinks in
~/.claude/skills/
- Run
opencode with Bun runtime
- Process crashes with ENAMETOOLONG during skill discovery
Environment
- Runtime: Bun 1.3+
- OS: macOS (confirmed), likely affects Linux too
- Affected directories:
~/.claude/skills/, ~/.agents/skills/
Proposed Fix
Pre-scan directories for circular and broken symlinks before glob traversal, and pass detected paths as ignore patterns to glob. Key changes:
packages/core/src/util/glob.ts: Expose ignore option in Glob.Options
packages/opencode/src/skill/index.ts: Add findBrokenSymlinks() that recursively detects circular symlinks (via readlink + path resolution + realpath visited set) and broken symlinks (via stat ENOENT/ELOOP), then passes results as glob ignore patterns
Bug Description
On Bun runtime, opencode crashes with
ENAMETOOLONGerror during skill scanning when external skill directories (e.g.~/.claude/skills/,~/.agents/skills/) contain circular or broken symlinks.Root Cause
The skill discovery system uses
globwithfollow: trueto scan external skill directories. When circular symlinks exist (e.g.,skills/finishing-a-development-branch/finishing-a-development-branch→ points to itself), glob enters an infinite recursion. On Bun runtime, this causes path strings to exceedPATH_MAX, triggeringENAMETOOLONGfromreaddirwhich crashes the process. Node.js handles this gracefully, but Bun does not.Additionally, broken symlinks (target deleted) cause unnecessary I/O errors during scanning.
Reproduction
~/.claude/skills/opencodewith Bun runtimeEnvironment
~/.claude/skills/,~/.agents/skills/Proposed Fix
Pre-scan directories for circular and broken symlinks before glob traversal, and pass detected paths as
ignorepatterns to glob. Key changes:packages/core/src/util/glob.ts: Exposeignoreoption inGlob.Optionspackages/opencode/src/skill/index.ts: AddfindBrokenSymlinks()that recursively detects circular symlinks (viareadlink+ path resolution +realpathvisited set) and broken symlinks (viastatENOENT/ELOOP), then passes results as glob ignore patterns