anomalyco / anomalyco/opencode
External-skill discovery (skills/**/SKILL.md) is fully recursive with no depth limit, causing derailment when a tool vendors nested skill copies (e.g. gstack)
@nexxeln is already working on this.
Since Sep 16, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
OpenCode's external-skill discovery (confirmed via strings on the compiled opencode-darwin-arm64 binary, v1.18.31) uses the glob pattern skills/**/SKILL.md under ~/.claude and ~/.agents — fully recursive, no depth limit, applied on every run regardless of --dir or --pure.
This becomes a problem when a legitimately installed tool vendors copies of its own skills for other coding assistants inside its own directory tree. gstack (a Claude Code skill package) does exactly this by design — it vendors a full copy of its ~68-skill suite for 9 other tools (.opencode/skills/, .factory/skills/, .kiro/skills/, .cursor/skills/, .gbrain/skills/, .hermes/skills/, .slate/skills/, .agents/skills/, .openclaw/skills/) inside ~/.claude/skills/gstack/, so that whichever of those tools a user runs also picks up gstack's skills.
OpenCode's recursive glob walks straight into that vendored tree and loads all ~600 nested SKILL.md files as if they were its own available skills — confirmed in debug output: message=init count=65 on this machine, every run, regardless of which model or prompt was used.
Consequence, reproduced across 3 local model families (Qwen2.5-Coder 3B/7B, Qwen2.5-Instruct 7B, Llama-3.1-8B) via Ollama, 5 trials: every model, every trial, derailed mid-task into vocabulary lifted from those phantom skills. Example: one trial's model responded mid-task with "It seems like you are asking for the 'setup' skill instead... the correct command is 'setup [skill name]'" — setup is not part of the task's vocabulary anywhere; it is the literal name of several nested skills in the vendored tree (setup-deploy, setup-browser-cookies, setup-gbrain). --pure did not help (it only gates plugins, not this scan).
Fix confirmed: setting OPENCODE_DISABLE_EXTERNAL_SKILLS=1 drops init count from 65 to 1 (only the built-in customize-opencode skill remains), and two clean re-runs of the same sandbox task (a one-line Python bug + failing pytest test) showed zero skill-vocabulary derailment in either trial.
Suggested fix: don't recurse past a directory that already matched SKILL.md — treat it as one skill's own directory (which may legitimately contain its own nested files, including other tools' vendored SKILL.md copies), not a new search root to walk into.
Related existing reports on the same underlying gap (this report adds a concrete, reproducible model-behavioral consequence, plus the exact glob pattern from the binary, rather than just a performance/warning symptom):
- #46327 (open) — duplicate skill name warnings from nested/symlinked
SKILL.md - #29462 (closed) — skill enumeration has no upper bound
- #20647 (closed) — skill descriptions bloat system prompt, breaking small-context models
- #27027 (closed) — skill discovery follows symlinks into large directories, causing slow startup
Repro steps:
- Have any tool installed under
~/.claude/skills/<name>/that itself vendors nestedSKILL.mdcopies several directories deep (or simulate by creating~/.claude/skills/test/.opencode/skills/foo/SKILL.md,.factory/skills/bar/SKILL.md, etc.) - Run
opencode run --dir <any-project> --model <any-model> --print-logs --log-level DEBUG "<any task>" - Observe
message=init count=<N>in the log, where N includes every nestedSKILL.md, not just top-level~/.claude/skills/<name>/SKILL.mdentries - Compare against
OPENCODE_DISABLE_EXTERNAL_SKILLS=1 opencode run ...— count drops to 1, and the derailment stops
Environment: macOS 25.6.0 (Darwin), opencode-ai 1.18.31 (npm), Ollama-backed local models via @ai-sdk/openai-compatible provider.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.