Subagent `skills:` frontmatter preload does not inject skill content when the skill has `disable-model-invocation: true`
Summary
When a subagent's frontmatter declares skills: [<name>], the documented behavior
is that the full SKILL.md content is injected into the subagent's context at
startup (see sub-agents.md → Preload skills into subagents):
"The full content of each skill is injected into the subagent's context, not just made available for invocation."
In practice, if the target skill has disable-model-invocation: true in its
SKILL.md frontmatter, this explicit preload is silently skipped and the
skill is also unusable via the Skill tool from inside the subagent.
This conflates two orthogonal concerns:
disable-model-invocationis documented as preventing the **model from
auto-discovering/auto-invoking** a skill based on its description.
- Subagent
skills:is an explicit, developer-authored preload — the
decision has already been made at configuration time; no model auto-invocation
is involved.
Blocking the second on the basis of the first breaks the documented subagent
preload contract.
Related but distinct: #43875 covers the top-level session case (slash command
blocked, skill hidden from session listing). This issue is specifically about
the subagent skills: preload path, which the docs describe as content
injection rather than invocation.
Reproduction
- Create
~/.claude/skills/demo-skill/SKILL.md:
```yaml
---
name: demo-skill
description: Demo skill for repro.
disable-model-invocation: true
---
## Core Concept
CANARY_STRING_12345 — this line should appear in the subagent's context
if preload works.
```
- Create a project-level subagent at
.claude/agents/demo-agent.md (or the equivalent in your project config):
```yaml
---
name: demo-agent
description: Demo subagent that should have demo-skill preloaded.
skills:
- demo-skill
---
You are a demo agent.
```
- Invoke the subagent via the
Agenttool with
subagent_type: "demo-agent". Ask it to:
- (a) quote any line containing
CANARY_STRING_12345from its system context; - (b) try to call the
Skilltool withskill: "demo-skill".
Observed
- (a) The canary string is not present in the subagent's context. The
SKILL.md body is not injected.
- (b) The
Skilltool call is rejected with:
````
Skill demo-skill cannot be used with Skill tool due to disable-model-invocation
- MCP tools that the skill normally coordinates with (e.g.
mcp__chrome-devtools__* for a chrome-devtools skill) remain available via
ToolSearch in the subagent, but they are granted independently and carry
none of the SKILL.md guidance.
Flipping the SKILL.md to disable-model-invocation: false makes the SKILL.md
body appear in the subagent's context as documented.
Expected
Either:
- The subagent
skills:preload should honor the explicit declaration and
inject SKILL.md content regardless of disable-model-invocation, since
preload is not model auto-invocation; or
- Document this interaction explicitly in both
skills.md
and sub-agents.md,
and recommend a workaround for developers who want a skill that is both
(a) not auto-invoked in the parent conversation and (b) preloaded into a
specific subagent.
Impact
The common use case this breaks: a skill that is expensive or side-effectful
at the top level (so you want disable-model-invocation: true), but which is
exactly the right playbook for a dedicated subagent that the parent delegates
to. Currently the skills: frontmatter silently no-ops in this configuration,
which is especially confusing because the docs explicitly promise content
injection.
Environment
- Claude Code CLI 2.1.114, macOS (Darwin 25.3.0)
- Verified locally with both project-level and user-level combinations
(project subagent + project skill, user subagent + user skill). The
remaining cross-scope combinations (user/project, project/user) are likely
affected as well but were not exhaustively tested.
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗