skillOverrides silently ignored for plugin-provided skills — runtime hard-codes source==="plugin" to "on" while the /skills UI implies overrides work
Summary
skillOverrides (name-only / off / user-invocable-only) is silently ignored for plugin-provided skills: the runtime resolver hard-codes them to "on" before any key lookup. Meanwhile the /skills UI reads and displays override state for plugin skills as if the setting works — so users can set overrides that never take effect, with no warning.
Environment
- Claude Code 2.1.205 (npm global, macOS 15 / Darwin 25.5)
- Reproduced with marketplace plugins (
expo@claude-plugins-official,sentry-cli@claude-plugins-official,commit-commands@claude-plugins-official)
Repro
- Enable any marketplace plugin that ships skills (e.g.
expo@claude-plugins-official). - In
~/.claude/settings.json, set overrides for its skills — any key form:
``json``
"skillOverrides": {
"expo:building-native-ui": "name-only",
"sentry-cli:sentry-cli": "name-only"
}
- Also set a user-scope skill (from
~/.claude/skills/) toname-onlyas a control. - Start a new session and inspect the model's skill listing.
Expected: plugin skills render name-only (or hidden for off), same as user-scope skills.
Actual: plugin skills always render with their full (200-char-capped) descriptions; the user-scope control skill correctly renders name-only. Verified with 29 plugin-qualified name-only entries — none have any effect, while every bare user-scope key works.
Root cause (from the 2.1.205 bundle)
The effective-override resolver short-circuits on plugin source before any settings lookup:
function e9e(e){
if (e.type !== "prompt" || e.source === "plugin") return "on";
let t = Bn(), r = t.skillOverrides,
n = r?.[e.name] ?? (e.unqualifiedName != null ? r?.[e.unqualifiedName] : void 0) ?? "on";
...
}
This one function feeds the name-only listing set, the off invocation gate (WY), and model-invocability (iDo) — so all override modes are dead for plugin skills, regardless of key format.
The mismatch: the /skills panel's override logic does read user/project/local skillOverrides for plugin skills and renders the chosen state, so the UI implies support the runtime doesn't have. If the exclusion is intentional, the UI should refuse or warn; if not, the resolver should drop the source === "plugin" short-circuit.
Impact
There is currently no way to trim plugin skill descriptions from the per-turn skill listing short of disabling the entire plugin. Plugins with large skill sets (expo ships 15 skills ≈ 2.5k chars of listing) consume a big share of the ~1% listing budget, and past the budget, entries get truncated and skill routing degrades — so per-skill name-only on plugins is exactly the tool users reach for, and it silently does nothing.
Related
- #15281 — requested exactly this, but was auto-closed as a duplicate of #13954, which is about project-vs-user rules precedence, not plugin skill overrides; it's locked, hence this new issue.
- #50631 — earlier report that
skillOverrideswas ignored entirely (stub resolver). That's since been fixed for user/project skills, which is why bare keys now work; the plugin-source exclusion remains. - #22345 — adjacent: plugin skills also don't support
disable-model-invocationfrontmatter, closing off the author-side workaround too.
---
Investigated and drafted with Claude Code (binary-verified against 2.1.205); posted by the account owner.