Repository navigation
Cursor skill discovery drops all workspace skills when any user-level skills folder exceeds the scan depth limit #17215
Description
What happened
When using models through the Cursor provider, neither / slash commands nor $ skill mentions show any of the skills in my project. The project has 28 skills under .agents/skills and .claude/skills, and all of them have valid SKILL.md files.
Diagnosis
probeCursorSkills scans eight roots: .cursor/skills, .agents/skills, .codex/skills and .claude/skills, first under the workspace and then under the user's home. All eight share one CursorSkillScanBudget (10,000 entries, MAX_SKILL_DEPTH = 10). When any root contains a directory that goes past the depth limit, budget.exhausted is set (apps/server/src/provider/Drivers/CursorSkills.ts:207-210). probeCursorSkills then fails the whole probe with CursorSkillsProbeError(scan-budget-exhausted) (CursorSkills.ts:268-273), even though the project roots were scanned completely first. CursorDriver.snapshotForCwd (CursorDriver.ts:235-247) turns this into a ProviderDriverError, and the registry logs "provider registry refresh failed; preserving cached providers". As a result, the composer never gets the workspace skills.
On this machine the deep tree is not a skill. It is leftover staging data from Claude's skill sync at ~/.claude/skills/synced/<id>/.staging/<pid>/pptx/pptx/scripts/office/schemas/ecma/fouth-edition, 11 levels below ~/.claude/skills. The two staging folders date from 6 days earlier, and their PIDs are no longer running. Without that folder, the deepest path under ~/.claude/skills is 8 levels, and Cursor skill discovery works.
Two behaviors make this worse:
- All-or-nothing failure. One over-deep or oversized directory in an unrelated user-level root discards every skill, including project skills that were already found. Returning the skills found so far (or degrading per root) would be more robust.
- Dot-directories are walked.
.staging,.trash,.git,node_modulesand similar are recursed into like any other folder. Claude's skill sync writes.staging/and.trash/inside~/.claude/skills, so any user who has Claude skill sync and a deep skill package (pptx, docx or xlsx shipscripts/office/schemas/...) can hit this. Skipping dot-directories, or not recursing below a directory that already contains aSKILL.md, would avoid it.
CursorSkills.ts on main is identical to v0.0.45, so this is not fixed upstream yet.
Steps to reproduce
- Use the Cursor provider on any workspace that has skills in
<workspace>/.agents/skills/<name>/SKILL.md. - Create a directory chain 11 or more levels deep under
~/.claude/skills, for examplemkdir -p ~/.claude/skills/x/.staging/1/a/b/c/d/e/f/g/h/i. - Open a Cursor thread in the workspace and type
$or/in the composer. - No workspace skills are listed.
server.trace.ndjsonshowsCursorSkillsProbeError ... (scan-budget-exhausted). - Remove the deep directory, then restart or refresh providers. The workspace skills appear.
Version
0.0.45 (v0.0.45, 6c8fed3)
Environment
Windows 11 Pro 10.0.26200 x64, Node v26.8.2, T3 Code desktop app with a local server, cursor-agent 2026.09.23-86fc751
Evidence
{"type":"effect-span","name":"probeCursorSkills",...,"exit":{"_tag":"Failure","cause":"CursorSkillsProbeError: Cursor skill discovery for '<workspace>' was incomplete (scan-budget-exhausted).\n at probeCursorSkills (.../server.asar/apps/server/dist/bin.mjs:157608:79)\n at refreshWorkspaceSnapshot (.../bin.mjs:218988:40)\n at ws.rpc.server.refreshProviders (.../bin.mjs:100908:104)"}}
{"type":"effect-span","name":"refreshWorkspaceSnapshot",...,"exit":{"_tag":"Failure","cause":"ProviderDriverError: Provider driver 'cursor' failed to create instance 'cursor': Failed to discover Cursor skills for '<workspace>' ... [cause]: CursorSkillsProbeError ..."}}
{"type":"effect-span","name":"recoverRefreshFailure",...,"events":[{"name":"[\"provider registry refresh failed; preserving cached providers\", ...]"}]}
# Per-root scan (entries / max directory depth below the root):
<workspace>/.agents/skills 137 entries, depth 2
<workspace>/.claude/skills 137 entries, depth 2
~/.cursor/skills 2 entries, depth 1
~/.agents/skills 2 entries, depth 1
~/.codex/skills 71 entries, depth 3
~/.claude/skills 557 entries, depth 11 <- synced/<id>/.staging/<pid>/pptx/pptx/scripts/office/schemas/ecma/fouth-editionRelated issues
#16866: failed workspace discovery is cached and not retried. That is related (it is why the missing skills persist), but it covers retry and caching. This issue is about why the probe fails in the first place: an unrelated over-deep user-level directory aborts all Cursor skill discovery. #2736 (closed) had a similar symptom ("Cursor/OpenCode skill discovery returns zero skills") but predates the scan budget.
Fix applied or workaround
Moved the stale ~/.claude/skills/synced/<id>/.staging folder out of the skills tree, then restarted the T3 Code desktop app. The problem will come back whenever Claude's skill sync leaves another stale .staging folder.
Filed by
Claude Code (Claude Opus 5.5, claude-opus-5-5) via t3 triage
Activity
juliusmarminge commentedon Oct 8, 2026
Note
Grok responding on behalf of Julius.
Thanks for the detailed write-up. Reading the code on
main(12069eefd), the diagnosis looks right.What the code does
CursorSkillScanBudget: project.cursor/.agents/.codex/.claudeskills first, then the same four under home (CursorSkills.ts:225-246). Limits areMAX_SKILL_DEPTH = 10and 10,000 entries (:26-28).budget.exhausted = trueand stops (:207-210). Running out of entries does the same (:199-202). So hitting a limit in one subtree marks the whole scan as failed, rather than just skipping that subtree.probeCursorSkillsthen throwsCursorSkillsProbeError(scan-budget-exhausted)and discards skills it already found (:264-276).CursorDriver.snapshotForCwdturns that into aProviderDriverError(CursorDriver.ts:267-285). With no workspace snapshot, the composer appears to get no skills.node_modulesfilter (:198-211). It also keeps going below a directory that already has aSKILL.md(:163-191). That would explain why a stale~/.claude/skills/synced/<id>/.staging/...tree can reach the depth limit.Why it fails hard
Failing the probe appears to be deliberate. #9180, which added this scanner, says "Strict
probeCursorSkillsfails when scan budgets are exhausted". The same pattern in AntigravitySkills.ts:158 explains it: "Read failures remain typed so workspace snapshots do not cache partial results." That reasoning works for a transient read error. It doesn't work for a depth or entry limit, because the same tree fails the same way on every refresh, so retrying never recovers. A filesystem error in any root (budget.incomplete, :67, :249-253) also fails the whole probe, so an unreadable user-level folder could probably cause the same symptom.The other providers don't walk this deep. Claude reads only the direct children of each root and skips anything it can't read (ClaudeSkills.ts:315-347). Antigravity stops at the first
SKILL.mdand goes at most one level down (AntigravitySkills.ts:206-229). Grok and Codex get their skill lists from the CLI or app-server instead of scanning the filesystem.Possible fix (not yet verified against Cursor's own loader)
exhausted. Keep the entry budget as a real hard stop.node_modules. If Cursor's loader allows it, also stop descending once a directory has aSKILL.md.Related
CursorSkills.tsto add plugin skills. The plugin scan reuses the same shared budget and doesn't change the depth behavior. That would use up more of the shared entry budget, so the two changes may conflict.Workaround until then: move stale
.stagingor.trashfolders out of~/.claude/skills, as you did, then refresh providers.m4tta commentedon Oct 9, 2026
Same all-or-nothing failure here, but from the 10,000 entry budget, not the depth limit. #17389 doesn't cover this. It only changes the depth path and keeps the entry-budget failure on purpose (it adds a test that a root with more than 10,000 entries still fails the probe). So this case stays broken after that PR merges.
What happened
In one workspace, Cursor threads only showed
/modeland/usage-limitsin the composer. Other workspaces were fine, so it looked intermittent.Cause
A project skill writes its run output into its own folder,
<workspace>/.cursor/skills/verify-ava/artifacts/<run-id>/(screenshots, videos, transcripts). After a month that folder had 301 runs and 10,651 entries. Max depth was 8, so the depth limit wasn't involved.Project roots are scanned first. The budget ran out inside
<workspace>/.cursor/skills(remainingEntries === 0,CursorSkills.ts:199-202),probeCursorSkillsthrewscan-budget-exhausted, and every skill got dropped, including the ones it had already found.Also,
~/.agents/skillsis a symlink to~/.claude/skillson this machine.discoverSkillsInRootcreates a newvisitedDirectoriesfor each root, and both roots resolve to the same realpath, so the same 871-entry tree is charged to the budget twice. Skills get deduped by name, but the budget doesn't.Per-root scan before the workaround
Trace
Repro
.cursor/skills/<name>/SKILL.md.mkdir -p .cursor/skills/<name>/artifacts && for i in $(seq 1 11000); do touch .cursor/skills/<name>/artifacts/f$i; done/. No skills, and the trace showsscan-budget-exhausted.Suggestions beyond the triage comment
SKILL.md, if Cursor's loader allows it. Thennode_modules, build output or run artifacts next to aSKILL.mdwouldn't count.visitedDirectories(or a set of root realpaths) across roots so a symlinked root is only charged once.Workaround
Deleted the old run folders under
artifacts/and refreshed providers.Environment
T3 Code 0.0.45 (v0.0.45, 6c8fed3), desktop app (Nightly) with local server, macOS 26 arm64 (Darwin 25.5.0), Node v26.8.2.
Posted via
t3 triagewith Claude Code (Claude Opus 5.5, claude-opus-5-5).ScottN-PV commentedon Oct 11, 2026
Thanks for the detailed trace. I ran both cases with
probeCursorSkillson a real filesystem (Linux, Node 24), usingmain's scanner (unchanged from b9afba5 through bf725cb) and #17389's head (eedd33d). Both behave the same:SKILL.md:scan-budget-exhausted, no skills returned.~/.agents/skillssymlinked to a~/.claude/skillstree with 6,000 files:scan-budget-exhausted. The same tree without the symlink passes, so the budget charges it twice.#17389 only stops the depth limit from failing the whole scan. It leaves both of these as they are, and if it merges as is, it closes this issue. I can open a separate small PR for them.
For the symlink case I'd scan each real root once, keeping the current root order. The entry-budget case needs a maintainer decision, as in option 3 of the triage comment: keep failing hard, return the skills found so far with an incomplete flag, or give each root its own budget. Partial results alone keep the skills already found but still skip every later root, and the probe fails hard today so snapshots never cache a partial list. I'd give each root its own budget and skip only a root that runs out, with a log line, so one large skill folder can't hide the others. Stopping the walk at a
SKILL.mdwould also help, but I don't know whether Cursor's loader allows nested skills. Limits: Linux only, the probe called directly rather than through the composer, and none of these remedies tested yet.Maintainers, which option do you want?
Written by Claude Fable 5.1 and Claude Opus 5.5 on behalf of ScottN-PV.
Culpable commentedon Oct 15, 2026
The entry-budget case still reproduces after the depth-limit fix in #17389.
Environment:
A user-installed skill has test dependencies under:
~/.agents/skills/<skill>/tests/node_modules/With Cursor selected, the
$picker offers no skills. The server repeatedly logs:CursorSkillsProbeError: Cursor skill discovery for '' was incomplete (scan-budget-exhausted).
A read-only replay of the installed scanner’s directory walk reaches the shared 10,000-entry limit inside that node_modules tree. That single skill package accounts for approximately 8,849 entries before discovery stops. No filesystem errors occur.
The installed scanner includes #17389’s depth-limit change, but entry exhaustion still fails the entire probe and discards skills already discovered.
Proposed fix:
The composer needs skill metadata from SKILL.md. Installed test dependencies, supporting assets and run outputs must not make unrelated skills disappear.
Could this remaining case be tracked separately or the issue reopened? The depth fix does not resolve it.