Repository navigation
disable-model-invocation: true makes a skill unreachable, not manual-only (Skill not found on explicit invocation) #4438
Description
Summary
A project skill whose SKILL.md frontmatter carries disable-model-invocation: true is not reachable from the CLI at all. copilot skill list shows it under Project skills, but the model's skill() tool returns Skill not found: <name>, so an explicit user request for the skill fails too.
In Claude Code (where the field originated) and in Cursor, disable-model-invocation: true means "the model may not select this skill on its own; the user can still invoke it by name". The CLI appears to treat it as "do not expose this skill at all", which leaves no way to run the skill.
Version / environment
GitHub Copilot CLI 1.0.79- Linux (Fedora, kernel 7.0.13)
- Skill directory:
<repo>/.github/skills/socratic-method/, inside a git repository
Reproduction
Using a published skill that ships the field (socratic-method):
pipx install socratic-method
cd "$(mktemp -d)" && git init -q .
socratic-method setup copilot --copy # writes .github/skills/socratic-method/- The CLI discovers it:
$ copilot skill list
Project skills:
socratic-method - Interrogates the user's idea with disciplined Socratic questioning until hidden assumptions, ...- The model cannot reach it, even when named explicitly:
$ copilot -p 'Use the /socratic-method skill. Before asking me anything, reply with exactly
one line of JSON: {"loaded": true|false, "path": "<SKILL.md path>"}' --allow-all-tools --no-color
✗ skill(socratic-method) Skill not found: socratic-method
{"loaded": false, "path": ""}- Delete the
disable-model-invocation: trueline from.github/skills/socratic-method/SKILL.mdand re-run the same prompt — the skill loads normally:
● skill(socratic-method)
{"loaded": true, "path": "/tmp/tmp.XXXX/.github/skills/socratic-method/SKILL.md"}Isolation
Same sandbox, same prompt, only the frontmatter differs:
| Frontmatter | Result |
|---|---|
disable-model-invocation: true + user-invocable: true |
Skill not found |
disable-model-invocation: true only |
Skill not found |
| neither key | loads normally |
disable-model-invocation alone reproduces it; user-invocable is not involved. YAML comments elsewhere in the frontmatter are present in all three cases and are not a factor.
Expected
disable-model-invocation: true should keep the skill out of automatic selection while leaving it invocable when the user names it — matching the semantics of the agent that introduced the field, and matching what the field is for: skills with side effects, or long interactive workflows, that should only run on request.
If the CLI intends different semantics, that is worth documenting. Adding agent skills for GitHub Copilot CLI documents only name, description, license and allowed-tools, so today the behavior is silent: the skill installs fine, lists fine, and only fails at the moment of use.
Impact
Portable skills written against the shared SKILL.md format and published for several agents carry this field to get manual-only behavior wherever it is supported. On the CLI those skills are silently dead — nothing in skill list, in install tooling, or in the docs signals a problem until a user tries to run one.
Related but distinct: #3095 (adding capability declaration fields to frontmatter).
Activity
evals: mark the Copilot CLI breakage expected, and fail if it heals
grammy-jiang commentedon Aug 11, 2026
Additional evidence: this looks like a regression in the CLI, not intended semantics — and it contradicts documentation and code that GitHub itself ships.
1. The shipped docs specify the opposite
GitHub.copilot-chat0.48.1 bundlesextension/assets/prompts/skills/agent-customization/references/skills.md, which contains this table:user-invocable: falsedisable-model-invocation: trueSo
disable-model-invocation: trueis documented to keep the skill reachable as a slash command while removing it from automatic loading. That is exactly the behaviour the CLI does not provide.2. The SDK implements it correctly
@github/copilot1.0.39 (the version bundled in that same extension) builds the skill tool like this — minified, reformatted for readability:The
disableModelInvocationfilter shapes only what the model is told exists. Resolution goes throughg, the unfiltered list, so a skill carrying the flag is still loadable when the user names it. That matches the documented table.3. The CLI at 1.0.79 returns not-found instead
Same skill, same directory, reported in the original description:
✗ skill(socratic-method) Skill not found: socratic-method, whilecopilot skill liststill shows it under Project skills. The not-found branch means resolution failed, which under the 1.0.39 logic should be impossible for a discovered skill.I could not diff 1.0.79 directly: from ~1.0.65 the npm package is a loader stub and the JS lives inside the compiled binary, so the code path is no longer statically inspectable. 1.0.55/1.0.60 still ship
sdk/index.jsbut no longer contain theSkill not foundstring, so the message was reworded somewhere in between — which is roughly where the behaviour seems to have moved too.Why it matters
The failure is silent in every place a user would check: the skill installs fine,
copilot skill listshows it, and any installer's status check reports it healthy. It only fails at the moment of use. Portable skills published for multiple agents carry this field precisely to get manual-only behaviour, so on the CLI they are dead on arrival with no signal.Happy to test a fix against the original reproduction.
grammy-jiang commentedon Aug 15, 2026
Correction (2026-09-08): this was wrong — 1.0.80 did not fix it. The
loaded: truebelow was a false positive of my probe, not the skill tool. Retested with the identical reproduction on a genuine 1.0.80 and on 1.0.83; the original report stands on both. The original text is kept at the bottom for context.What the skill tool actually does (1.0.80 and 1.0.83)
Same setup as the issue (
socratic-method setup copilot --copyin a fresh git repo →<repo>/.github/skills/socratic-method/SKILL.md,disable-model-invocation: truepresent), with a prompt that forces the tool call:Control — delete the
disable-model-invocation: trueline, same prompt, both versions:The "Available skills" the tool lists are exactly the discovered skills without the flag, and resolution goes through that filtered list, so a flagged skill is
not foundeven when the user names it. That is the bug as originally reported, unchanged through 1.0.83. The 2026-09-01/02 reports above (~/.agents/skills, 1.0.82) are the same thing, and #4637 is the same bug seen from the slash-command side.Why my August run printed
loaded: trueThe August prompt did not force the tool call, and
--allow-all-toolswas on. Full transcript of that exact prompt on 1.0.80 today — there is noskill(...)line anywhere in it:Denied the skill, the model went looking for the file, read it with its own tools, and reported success — the same "Skill file loaded. Let me read the full SKILL.md" pattern as in my August output. On this machine it even picked a copy outside the sandbox. 1.0.83 does the same with the same prompt (it ends in four
● Read SKILL.mdchunks and{"loaded": true, …}, 448k tokens, noskill()call). A probe that trusts the model's self-reported path cannot tell this from a real load; the● skill(name)/✗ skill(name) Skill not foundline can.What does work: the interactive slash command (1.0.80 and 1.0.83)
Typed at the interactive prompt, same sandbox, flag present, with the answer required to contain something only the loaded body has:
No tool call between the command and the answer, on both versions: the slash path resolves the flagged skill and injects it, exactly as the bundled
skills.mdtable says ("Slash command: Yes"). Theskilltool does not. So:/skill-name …at the prompt; "Use the /skill-name skill." inside a sentence goes through the tool and fails;-phas no slash path (a leading/skill-namein the prompt is passed through as text), so a flagged skill is unreachable there.Bottom line
Upgrading is not the fix; the sentence "the breakage was present in 1.0.79 and is gone in 1.0.80" below is wrong and I retract it. The defect is the one in the issue body: explicit invocation through the
skilltool resolves against the model-filtered list. The interactive slash command is currently the only path that honors the documented semantics.Environment for the retest: GitHub Copilot CLI 1.0.80 via
npx -y @github/copilot@1.0.80 --no-auto-updatewithCOPILOT_AUTO_UPDATE=false(without those the CLI self-updates at launch — every 1.0.80 run was checked againstStarting Copilot CLI: 1.0.80in~/.copilot/logs/), and the installed 1.0.83; Linux aarch64; model claude-opus-4.8; socratic-method 0.5.1.Original comment (2026-08-15) — retracted, kept for context
Fixed in 1.0.80. Re-ran the original reproduction against
@github/copilot@1.0.80(published 2026-08-14) and both halves of the documented behaviour now hold.Same skill, same directory,
disable-model-invocation: truestill present in the frontmatter (verified before running):Explicit invocation — previously
Skill not found:Automatic invocation still suppressed — a prompt lifted from the skill's own description triggers is answered by Copilot directly, with no
skill()call and no artifact written:That is exactly the table in the bundled
skills.mdreference: slash command yes, auto-loaded no. Thanks for sorting it.For anyone finding this from a search: the breakage was present in 1.0.79 and is gone in 1.0.80 — upgrading is the fix, no frontmatter change needed.
anatskiy commentedon Sep 1, 2026
I can still reproduce this for personal skills in
~/.agents/skillson Linux with Copilot CLI1.0.82.Minimal reproduction
Create
~/.agents/skills/repro-skill/SKILL.md:Then run:
repro-skillis listed as available.Now run:
copilot -p 'Use the /repro-skill skill. Reply with exactly one short sentence.' --allow-all-tools --no-custom-instructionsActual result:
Removing
disable-model-invocation: truemakes the same explicit invocation succeed.In my installation, 44 personal skills are discovered and 21 contain this flag. An unflagged personal skill loads successfully. The reported fix appears not to cover
~/.agents/skillspersonal skills, or has regressed in1.0.82; the1.0.80reproduction may be using a repository.github/skillsskill instead.dustintran333 commentedon Sep 2, 2026
This is NOT fixed in 1.0.80 for skills located in
~/.agents/skills. I'm surprised that such a fairly fundamental contract is still exposing edge cases. This would render LOTS of skills unusable.Bozodragon commentedon Sep 11, 2026
Additional desktop-app evidence: this also occurs in GitHub Copilot desktop on Windows with a project-local
/wayfinderskill containingdisable-model-invocation: true.The session record confirms that the explicit slash invocation successfully injects
<skill-context name="wayfinder">with the skill instructions. The assistant then redundantly callsskillwith{"skill":"wayfinder"}, which returnsSkill not found: wayfinder.The desktop UI displays "Failed to load skill," even though the assistant continues using the already-supplied instructions. This is a recurring, confusing user-facing error, not just a failed invocation: the workflow can proceed while the UI suggests it failed.
Consolidating my report here from #4637, which was identified in its comments as a duplicate.
vadim-kovalyov commentedon Sep 15, 2026
Additional
msft-dogfoodreproduction through Agency:2026.9.3.9(96140c1d), Linux x86_641.0.82~/.agents/skills/manual-only-test/SKILL.md:agents/openai.yaml:When
/manual-only-testis entered, the explicit slash-command path succeeds and injects<skill-context name="manual-only-test">. The assistant then redundantly calls the model-facing Skill tool, which returns:Expected: once the explicit slash-command path has injected the skill context, the assistant should follow it directly without a second lookup through the model-visible registry. The policy should block implicit selection only, not the explicit invocation already in progress.
akiselevaristek commentedon Sep 22, 2026
Still reproducible in Copilot App 1.0.84-5 on macOS
I can reproduce this in a brand-new GitHub Copilot App session on macOS with the runtime/build reporting
1.0.84-5.Personal skill:
Relevant frontmatter:
Reproduction:
/to-specwith task text.to-specis omitted from the model-facing available-skills registry.skill("to-spec")lookup returnsSkill not found.Additional isolation: unflagged skills from the same
~/.agents/skillsdirectory are available, while local skills carryingdisable-model-invocation: true(includingto-spec,triage, andimplement-spec) are omitted. Restarting with a completely new session does not change the result.Expected behavior remains the documented manual-only behavior: an explicit user
/to-specinvocation should load the skill, while autonomous model selection remains disabled. The current App behavior appears to apply the model-facing filtered registry to explicit user invocation as well.Omzig commentedon Sep 25, 2026
Additional repro from GitHub Copilot App 1.0.87-0 on Windows:
/grill-with-docsappears in the slash-command popup, and I invoke it there.grill-with-docsis not registered and falls back to/grilling+/domain-modeling.Skill not found: grill-with-docs. The available-skill list includesgrillinganddomain-modeling, but notgrill-with-docs.In this repro, the popup exposes the command, but the skill resolver cannot resolve the same name; the requested skill itself does not load. That differs from cases where slash invocation injects the skill context and only a redundant second lookup fails. This points to a mismatch between slash-picker discovery and the model-facing skill registry, though I cannot tell from the repro whether the cause is separate registries, scope, or stale state.
jakob-schultheis commentedon Sep 30, 2026
Please fix this issue, it is really making the agents go in circles or lead to unexpected behaviour. Thank you 🙏
Omzig commentedon Sep 30, 2026
ya i dont like thrashing tool calls
jesusgalhub commentedon Oct 2, 2026
This is really annoying for a agentic-first app
Remove the sources list from maintaining-skills
feat(skills)!: move the remaining prompts into skills and agents (mic…
feat(skills)!: move the remaining prompts into skills and agents (#3111)
fix(skill): correct audit-conventions skill links and reachability
fix(skill): correct audit-conventions skill links and reachability
fix(skill): correct audit-conventions skill links and reachability
jaydeboer commentedon Oct 19, 2026
This would be really nice to have official support for. Is this fixable in Copilot?
Leave disable-model-invocation off the dispatch skill until hosts kee…
Leave disable-model-invocation off the dispatch skill until hosts kee…
docs(skills): record disable-model-invocation behaviour per harness (#…