Skip to content

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

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

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