[BUG] User skills listing silently absent from system prompt for an entire session — prose skill triggers fail, slash commands still work (one-off, v2.1.226)

Status Open
Reported on v2.1.226
Maintainer reply None cached
Activity 1 comment · opened Aug 9, 2026

What's Wrong?

On v2.1.226, one interactive session started with the entire user-invocable skills listing absent from the system prompt, and it stayed absent for the whole session (~4 hours, ~400 transcript records). The ~/.claude/skills directory (a symlink into a git repo, in place for months) was healthy and readable throughout — the model successfully ran ls ~/.claude/skills/ and cat ~/.claude/skills/wrapup/SKILL.md mid-session while the listing remained missing from context.

Observable effects:

  • Typed slash commands still worked (/startup as the first prompt expanded normally), so skill resolution was intact — only the system-prompt listing was missing.
  • Description-based (prose) skill triggering failed: in 26 consecutive prior sessions in this project, the phrase "wrap up" made the model invoke Skill(wrapup); in the affected session it improvised the procedure instead, and when challenged stated the only protocol in its context was /startup.
  • The failure was silent: no error, no warning, nothing in /doctor-visible state. From the user's side the session looked completely normal until a skill-dependent behavior quietly didn't happen.

One occurrence across hundreds of sessions on this machine. The next session in the same project two hours later was normal. Not reproducible on demand — but the transcript evidence below is conclusive that the block was genuinely absent server-request-side, not "present but ignored by the model."

What Should Happen?

The skills listing should be included in the system prompt every session. If the session-start skill scan fails or returns empty while the skills directory exists and is non-empty, that should be loud — a warning at startup or a /doctor finding — because a silently empty scan is indistinguishable from "no skills installed" and degrades the entire session downstream.

Error Messages/Logs

None — the failure is silent (that's part of the report). Evidence from transcript token accounting instead:

First-request usage from session .jsonl transcripts (input_tokens + cache_creation_input_tokens + cache_read_input_tokens), same project, all v2.1.226, byte-identical recorded first message (80 chars), no CLAUDE.md modified between sessions:

| Session start (UTC) | First-request total tokens |
|---|---|
| Aug 8, afternoon (healthy) | 39,029 |
| Aug 8, evening (healthy) | 38,686 |
| Aug 9, 04:37 (affected) | 36,328 |
| Aug 9, ~10:45 (healthy) | 39,035 |

The affected session's first request is ~2,400–2,700 tokens smaller — the size of the full skills-listing block. Since the recorded conversation content is identical across all four sessions, the deficit can only be in system-side prompt assembly.

Ruled out:

  • Filesystem/symlink failure — proven readable mid-session (see above)
  • Version regression — three healthy v2.1.226 sessions bracket the affected one
  • Config changes — none between the sessions
  • Model attention failure — the token deficit is request-side, before the model sees anything

How to check whether you've hit this

If a session ever "forgot" your skills (prose triggers stopped working, or the model claimed a skill doesn't exist while /skillname still worked), this scans your transcripts for first-request token outliers within each project:

python3 - <<'EOF'
import json, glob, os, statistics
for proj in sorted(glob.glob(os.path.expanduser('~/.claude/projects/*'))):
    first = {}
    for f in glob.glob(os.path.join(proj, '*.jsonl')):
        for line in open(f):
            try: r = json.loads(line)
            except Exception: continue
            if r.get('type') == 'assistant':
                u = r.get('message', {}).get('usage', {})
                first[os.path.basename(f)] = (u.get('input_tokens', 0)
                    + u.get('cache_creation_input_tokens', 0)
                    + u.get('cache_read_input_tokens', 0))
                break
    if len(first) >= 3:
        med = statistics.median(first.values())
        for name, tok in sorted(first.items()):
            if med - tok > 1500:
                print(f"{os.path.basename(proj)}  {name[:8]}  first-request {tok} "
                      f"vs project median {int(med)}  (-{int(med - tok)})")
EOF

A flagged session is a candidate, not proof — CLAUDE.md growth over time and CC version changes also move first-request size. Confirm by checking whether that session failed to use skills it should have (in my case: 26/26 prior sessions invoked the skill from prose; the flagged one didn't). If you find one, please comment with the numbers.

Environment

  • Claude Code 2.1.226, interactive TUI
  • Ubuntu 26.04 (Kubuntu), bash
  • User-level skills: ~/.claude/skills → symlink to a git-tracked directory, 7 skills; works in every other session

Additional Information

Related but distinct closed issues (this is not a duplicate of any of them):

  • #38051 — symlinked ~/.claude/skills not loading: a standing regression, failed every session; mine was one-off with the symlink proven healthy
  • #27703, #43092 — skills disappearing mid-session; mine was absent from the very first request and never appeared
  • #21635 — unrelated bug, but a process data point: labeled bug + has repro, then auto-staled and locked with no resolution — hence the emphasis here on evidence others can reproduce against their own transcripts

For searchability, other phrasings of this symptom: skills not listed in context; skills missing at session start; Claude says a skill doesn't exist but it's in ~/.claude/skills; prose/description trigger for a skill stopped working; skill won't auto-trigger but slash command works; system prompt missing the available-skills block; Skill tool shows no skills.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗