Where does the bug appear (feature/product)?
Cursor CLI
Describe the Bug
cursor-agent CLI’s TUI silently fails — every prompt produces an endless “Reconnecting…” spinner — when the combined size of all discovered SKILL.md files exceeds ~11 MB. Threshold is byte-based, not count-based: 220 small skills (50 KB each) and 32 large skills (1 MB each) both trigger it.
Underlying server rejection (visible only via agent --debug): NGHTTP2_ENHANCE_YOUR_CALM (HTTP/2 flow-control). The CLI retries 10 times then surfaces Connection failed repeatedly. With network.useHttp1ForAgent: true the same root cause surfaces more cleanly as Bad Request: Append data exceeds maximum size of 52428800 bytes against api2.cursor.sh.
The skill scanner uses recursive globs (**/.agents/skills/**/SKILL.md, **/.cursor/skills/**/SKILL.md, **/.claude/skills/**/SKILL.md, **/.codex/skills/**/SKILL.md, **/AGENTS.md, **/CLAUDE.md) and bundles every match into the per-turn request payload. There is no .cursorignore honoring on the skill loader, no env var, no config to scope skill discovery.
Multi-agent skill packs make this trivial to hit. gstack (GitHub - garrytan/gstack: Use Garry Tan's exact Claude Code setup: 23 opinionated tools that serve as CEO, Designer, Eng Manager, Release Manager, Doc Engineer, and QA · GitHub) ships every skill 9× — one canonical + per-runtime wrappers for .hermes, .openclaw, .opencode, .factory, .gbrain, .kiro, .slate, .cursor, .agents. A single gstack install with ~43 skills becomes ~390 SKILL.md (~28 MB) because the recursive glob matches every wrapper. On my machine: 1408 SKILL.md loaded, ~77 MB skill payload, TUI completely unusable.
Steps to Reproduce
- Plant 250 synthetic SKILL.md files of ~50 KB each:
mkdir -p ~/.agents/skills/_repro
for i in $(seq 1 250); do
mkdir -p ~/.agents/skills/_repro/skill_$i
python3 -c "print('---\nname: s$i\ndescription: x\n---\n' + 'x' * 49000)" \
> ~/.agents/skills/_repro/skill_$i/SKILL.md
done
- Launch TUI with debug logs:
agent --debug --model composer-2.5
- Type any prompt (e.g. “what is 2 plus 2”) and press Enter
- Spinner shows “Composing” then UI freezes on “Reconnecting…”
- Inspect
$TMPDIR/cursor-agent-debug-*/session.log:
AgentSkillsCursorRulesService load completed { ruleCount: 1408, skillCount: 1408 }
[nal_agent_retries] Initial request { attempt: 0 }
ConnectError: Stream closed with error code NGHTTP2_ENHANCE_YOUR_CALM
[nal_agent_retries] Error not retryable
turn.outcome { outcome: "error", error_code: "ERR_HTTP2_STREAM_ERROR",
error_text: "Connection failed repeatedly" }
- Cleanup:
rm -rf ~/.agents/skills/_repro
Threshold sweep (byte-based, not count-based)
Held baseline constant (14 plugin/cloud-rule skills, ~0.7 MB), varied N synthetic SKILL.md files of 50 KB each. Binary-searched the boundary:
| Synthetic added | Total skills | Total skill bytes | Result |
|---|---|---|---|
| 205 | 217 | ~10.85 MB | pass |
| 206 | 218 | ~10.90 MB | pass |
| 207 | 219 | ~10.95 MB | pass |
| 208 | 220 | ~11.00 MB | fail — NGHTTP2_ENHANCE_YOUR_CALM |
| 275 | 287 | ~14.4 MB | fail |
| 500 | 512 | ~25.6 MB | fail |
| 32 × 1 MB | 32 | ~20 MB | fail |
| 62 × 1 MB | 62 | ~50 MB | fail |
Failure is byte-based: 32 × 1 MB (20 MB total) fails the same as 220 × 50 KB (11 MB total). Threshold sits at ~11 MB on the default HTTP/2 endpoint (agentn.global.api5.cursor.sh). A separate higher 50 MB hard limit exists on api2.cursor.sh (HTTP/1 path).
Expected Behavior
Either of these would fix it cleanly:
-
cursor-agent honors
.cursorignore(or a new.skillignore) in the SKILL discovery glob, so users can scope the scan. CurrentlyignoreServiceonly gates file-read / grep operations — extend it (or add a parallel filter) intoAgentSkillsCursorRulesService.loadSkillsFromDirectoryand the recursive glob. -
cursor-agent supports a config option in
~/.cursor/cli-config.jsonto scope skill roots:{
“agentSkillRoots”: [“~/.cursor/skills-cursor/”, “~/.agents/skills/gstack/”],
“agentSkillIncludeWrappers”: false
}Default behavior unchanged; opt-in for users who hit the limit.
-
At minimum (UX fix): when
NGHTTP2_ENHANCE_YOUR_CALMor the 50 MBBAD_REQUESTfires, the TUI surfaces “Your skill bundle is too large (NN MB > 11 MB). Runagent --skills-listto prune.” instead of looping silently on “Reconnecting”. Right now the only signal is the spinner forever, sending users down the wrong debugging path (network, auth, MCPs).
Operating System
MacOS
Version Information
CLI:
CLI Version 2026.05.24-dda726e
Model Composer 2.5
Subscription Tier Pro
OS darwin (arm64, macOS 15.4)
For AI issues: which model did you use?
used all models.
mainly → Composer 2.5
For AI issues: add Request ID with privacy disabled
Request ID: c8a20849-a240-49d4-8399-028f92a871d9
Note: this run was captured with privacyMode: 2 (ghost mode) enabled, so the server-side trace may be unavailable. Happy to re-run with privacy disabled if needed — just let me know.
Additional Information
Workarounds tried (none fix the underlying limit):
-
.cursorignoreat the skill root — ignored by the SKILL scanner. OnlyignoreServicefor file reads honors it. Skill count unchanged. -
network.useHttp1ForAgent: true— switches endpoint toapi2.cursor.shand surfaces the cleaner 50 MBBAD_REQUESTerror, but does not raise the per-stream allowance. -
Removing one runtime’s gstack wrappers (1408 → 974 skills) — still fails (~50 MB payload, way over 11 MB threshold).
-
agent --print(headless) — happens to succeed more often because each invocation opens a fresh short-lived stream that survives flow-control more often. Not a fix; same payload is sent.
Effective workaround: physically delete SKILL.md files from disk until total bytes drop below ~11 MB. On my machine I pruned 1408 → 218 SKILL.md (77 MB → 9.28 MB) by removing per-runtime gstack wrappers — after that, TUI works (turn.outcome: outcome=success). But this is destructive and breaks skills the user wants available to other agent runtimes.
Related: This pattern also hits Claude Code (less severely — Claude Code drops skills gracefully with a “N skill descriptions dropped” warning instead of freezing). Filed a related issue on the gstack side asking them to stop shipping 9× duplicates: Skill files generated for other AI hosts pollute Claude Code's skill scanner · Issue #1694 · garrytan/gstack · GitHub
Even after gstack restructures, the Cursor-side ask stands: any recursive skill loader with no scoping mechanism is vulnerable to this from any sufficiently large skill pack.
Does this stop you from using Cursor
Yes - Cursor is unusable