Skip to content

skill: "Unable to load skill <name>" does not hint when the name is a registered agent #46568

Description

@Julfried

Summary

When a model invokes the skill tool with the name of a registered agent
instead of a skill, the only feedback is Unable to load skill <name>. The
error does not distinguish "unknown skill" from "permission denied" from "this
name belongs to an agent". Because user @-mentions of agents look similar to
skill invocations, models conflate the two registries, and the opaque error
sends the conversation into a manual debugging loop instead of a one-step
self-correction.

Environment

  • opencode version: v0.0.0-beta-18743 (opencode2, V2)
  • OS: Linux 7.1.12-200.fc44.x86_64 (Fedora 44, x64)
  • Terminal: ghostty (TERM=xterm-256color, COLORTERM=truecolor)
  • Shell: /bin/bash
  • Install/channel: beta
  • Active plugins: none (no plugin config, no .opencode/plugin/)

Reproduction

  1. Define a subagent at ~/.config/opencode/agents/my-agent.md with
    mode: subagent in the frontmatter (any name works; no skill with the
    same name is defined).
  2. In a session, ask the model to do a task "using @my-agent".
  3. Observe the model call the skill tool with name: "my-agent".

Expected Behavior

The skill tool error should be actionable. Ideally:

  • Unable to load skill my-agent: unknown skill. "my-agent" is a registered agent; invoke it with the subagent/task tool. when the name matches an
    agent, or minimally
  • Unable to load skill my-agent: no skill with this name is available in this session — i.e. distinguish "not found" from "permission denied", and point
    at similarly named registered entities (skills and agents).

Actual Behavior

All failure modes collapse into the same opaque message:

Unable to load skill my-agent

From packages/core/src/tool/skill.ts, unableToLoad(name) is used for both
the not-found path (skills.list() miss) and mapped load/permission errors,
so the model cannot tell why the load failed or what the correct tool would
have been. In practice this required a manual config investigation
(agents directory, skills list) to work out that the mentioned name was an
agent, not a skill.

Additional Context

  • The user config was correct: mode: subagent agent definitions in
    ~/.config/opencode/agents/ are the intended mechanism, and the same
    session successfully invoked a different agent via the proper tool.
  • The confusion seems easy to trigger because @-mentions of agents and
    skill names appear in similar prompt positions, and both registries are
    name-based.
  • Related open issue: [FEATURE]: stop using Effect.die for skill-not-found in the skill tool #40091 (skill-not-found error handling uses
    Effect.die) touches the same code path, but is about crash-style failure
    handling rather than error-message quality / agent cross-referencing.
  • Frequency: reproduced 3 times across one session (each failed skill load
    recovered only via manual fallback).
  • Workaround: none within the session; the model fell back to manually
    executing the agent's instructions (loading the referenced skill and
    calling the repository CLI directly), which produced correct output but
    bypassed the subagent isolation.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions