Skip to content

fix(skill): base directory URL-encoding breaks read tool when skill path contains # (e.g. git-tagged plugin cache) #33513

Closed as duplicate

Description

@shyuan

Description

The skill tool emits the skill's base directory as a file:// URL (via pathToFileURL(dir).href in packages/opencode/src/tool/skill.ts:30). This breaks when the skill directory path contains characters that get URL-encoded — most notably #, which becomes %23.

When a plugin is installed from a git URL with a version tag (e.g. writing-humanizer@git+https://github.com/.../writing-humanizer.git#v1.3.0), npm uses the full string including #v1.3.0 as the cache directory name. The skill's <location> then becomes file:///.../writing-humanizer.git%23v1.3.0/.../SKILL.md.

The LLM, trying to read a reference file listed in SKILL.md via a relative path, derives the absolute path from the base directory and passes ...git%23v1.3.0/.../references/foo.md to the read tool. But the filesystem path actually contains #, not %23 — so read returns "File not found". The skill appears broken (references missing) even though the files are installed correctly.

This also affects ACP editors (#23885) since the file:/// prefix itself is passed to read tools that expect plain filesystem paths.

Suggested fix: emit dir (plain filesystem path) as the base directory instead of pathToFileURL(dir).href. The <file> entries on the next line already use path.resolve(dir, file.path) (plain paths), so the base should match.

Plugins

writing-humanizer@git+https://github.com/shyuan/writing-humanizer.git#v1.3.0

OpenCode version

1.17.5

Steps to reproduce

  1. Add a plugin installed from a git URL with a version tag to opencode.json:
    { "plugin": ["writing-humanizer@git+https://github.com/shyuan/writing-humanizer.git#v1.3.0"] }
    The plugin registers skills/ via the config hook (injects config.skills.paths).
  2. The skill's SKILL.md links reference files via relative paths, e.g. references/zh-tw-slop-list.md.
  3. Load the skill via the skill tool and ask the agent to read a reference file.
  4. The agent derives the path from the Base directory field (which contains %23) and the read tool fails with "File not found".

Confirmed by reading the same file with %23 (fails) vs # (succeeds) in the path.

Screenshot and/or share link

Source of the bug: https://github.com/anomalyco/opencode/blob/dev/packages/opencode/src/tool/skill.ts#L30

Related: #23885 (ACP file:/// prefix), #18370 (skill path resolution)

Operating System

macOS 15.5

Terminal

iTerm2

Activity

  1. github-actions commented on Jun 23, 2026

    @github-actions
    Contributor

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

    It may be worth coordinating or closing one in favor of the other.

  2. shyuan commented on Jun 24, 2026

    @shyuan
    ContributorAuthor

    Closing as duplicate of #18370 — same underlying problem (skill base directory paths not resolving correctly). The precise root cause is pathToFileURL(dir).href in packages/opencode/src/tool/skill.ts URL-encoding the base directory (e.g. # → %23 for git-tagged plugin cache dirs), so the LLM derives a path the read tool can't open. Fix in #33580.

  3. added a commit that references this issue on Jun 24, 2026
    8beda82
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