DEV Community

Anup Karanjkar
Anup Karanjkar

Posted on • Originally published at wowhow.cloud

Claude Code's skillListingBudgetFraction: The Undocumented Setting Silently Killing Half Your Skills

I run 27 skills in Claude Code. Custom skills I have built for WOWHOW, ecosystem plugins from wshobson, the graphify integration, the Supabase agent, the Cloudflare MCP bridge — 27 total. For about three weeks, I had a subtle problem: certain skills would trigger reliably on Monday and then go silent by Thursday of the same week. Not broken. Not misconfigured. Just… absent. The skill keyword would appear in my message, the trigger condition was clearly met, and the model would proceed as if the skill did not exist.

I blamed my trigger definitions. I rewrote them. I tightened the keywords. I rebuilt two skills from scratch. The problem persisted. It was not the trigger definitions. It was a setting I had never heard of, buried in Claude Code's internal config, that was quietly dropping skills from the context on every single turn — and the model never saw them because they were never listed.

The setting is called skillListingBudgetFraction. Here is everything I found.

The Symptom in Detail

The failure mode has a specific fingerprint. If you are experiencing it, you will recognize these characteristics:

  • Skills fail to trigger intermittently, not consistently. The same skill works in a fresh session and fails in a long session.

  • There is no error. No warning in the Claude Code output. The model does not say "I could not load skill X." It simply behaves as if the skill were not installed.

  • The failure rate increases as conversations get longer. Short sessions are fine. Sessions past the 20-30 turn mark start losing skills.

  • If you open a brand-new Claude Code session and try the same skill, it works immediately.

  • The skills that fail are not always the same ones. Different sessions drop different skills from the visible set.

That last point is the tell. If the same skill always failed, you would debug that skill. But when which skills fail varies session to session, the problem is not in any individual skill — it is in the selection mechanism that decides which skills to expose to the model on a given turn.

What skillListingBudgetFraction Actually Does

Claude Code has a skill system that works roughly as follows: installed skills have metadata — a name, a description, trigger conditions, and usage instructions. Before each model call, Claude Code assembles a skill listing: a block of text that enumerates the available skills and their descriptions. This listing is injected into the context so the model knows what tools it has available. When the model decides a skill is relevant, it signals Claude Code to load and execute that skill.

The skill listing is not free. It consumes tokens. Twenty-seven skills, each with a name, trigger description, and brief usage summary, consumes somewhere between 3,000 and 6,000 tokens depending on how verbose each skill's metadata is. On a model with a 200,000-token context window, that is 1.5% to 3% of the window — not catastrophic in isolation.

But Claude Code does not have an unlimited token budget for skill listings. It has a fraction. skillListingBudgetFraction is the percentage of the remaining context budget that Claude Code is willing to spend on skill listings per turn. "Remaining" is the operative word: it is not a fraction of the maximum context window. It is a fraction of what is left after the system prompt, conversation history, and other injected context have consumed their share.

In a long conversation, the remaining context budget shrinks. As it shrinks, the absolute token count available for skill listings shrinks proportionally. When the available tokens fall below what it would cost to list all installed skills, Claude Code truncates the listing. Skills at the bottom of the listing order do not get included. The model never sees them. It cannot invoke what it cannot see.

This is not a bug. It is a deliberate design decision. The alternative — always including all skills regardless of context pressure — would push out conversation history or system prompt content, which are arguably more important. The problem is that the default fraction is set conservatively, and it is not documented anywhere in the Claude Code user-facing materials as of version 2.1.129.

How to Find It

The setting lives in the Claude Code settings JSON. There are two places to check.

Global config (applies to all projects):

~/.claude/settings.json
Enter fullscreen mode Exit fullscreen mode

Project-level config (overrides global for a specific project):

.claude/settings.json
Enter fullscreen mode Exit fullscreen mode

Check both. On most installations that have never explicitly set this value, neither file will contain skillListingBudgetFraction at all. Its absence means Claude Code is using its compiled default, which I will discuss in the next section.

To see the effective value at runtime, the most reliable approach is verbose logging. Start Claude Code with verbose output:

claude --verbose
Enter fullscreen mode Exit fullscreen mode

Then watch for lines that contain skillListing or budgetFraction in the output. In Claude Code 2.1.129, the verbose log emits a line like this at the start of each turn:

[skills] budget=12800 tokens, fraction=0.04, installed=27, listed=11, dropped=16
Enter fullscreen mode Exit fullscreen mode

That single line tells you everything. In this example: the turn has 12,800 tokens available for skill listings (the absolute budget), the fraction in effect is 0.04 (4%), 27 skills are installed, only 11 are being listed, and 16 are silently dropped every single turn.

If you do not see this line in verbose mode, check your Claude Code version. The logging was added in 2.1.127. Earlier versions drop skills silently without any log output.

To get the compiled default without running Claude Code, you can inspect the binary. This is the approach I used when I first discovered the issue — I wanted to understand the default before changing anything:

# Find the Claude Code binary
which claude
# → /usr/local/bin/claude

# On macOS, strings extraction
strings /usr/local/bin/claude | grep -i 'skillListingBudget'
# → skillListingBudgetFraction
# → 0.04
Enter fullscreen mode Exit fullscreen mode

The compiled default is 0.04 — 4% of remaining context per turn. For most users with fewer than 10 skills, this is fine. For anyone running 20+ skills, it is a quiet disaster.

The Math

Let me show the token math concretely, because this is where the problem becomes obvious.

A typical Claude Code session with a medium-length conversation might look like this as context consumption:

Context window total:      200,000 tokens
System prompt:             ~2,400 tokens
Conversation history:      ~45,000 tokens (after 30 turns)
Tool definitions:          ~3,200 tokens
Other injected context:    ~1,800 tokens
─────────────────────────────────────────
Remaining budget:          ~147,600 tokens

Skill listing budget:      147,600 × 0.04 = 5,904 tokens
Enter fullscreen mode Exit fullscreen mode

5,904 tokens sounds like a lot until you count your skills. My skills average about 220 tokens each when their full metadata is included (name, trigger description, usage summary, parameter descriptions). Twenty-seven skills at 220 tokens each is 5,940 tokens — 36 tokens over budget.

So on that turn, I get 26 skills listed. One is dropped. Which one? The last one in the listing order, which in my setup happens to be a skill I use frequently. This is why it appeared random — different conversation lengths produce different remaining budgets, which produce different cut-off points, which drop different skills.

Now extend that to a longer session:

Conversation history:      ~90,000 tokens (60 turns)
Remaining budget:          ~102,600 tokens

Skill listing budget:      102,600 × 0.04 = 4,104 tokens
Skills that fit:           4,104 ÷ 220 = 18 skills
Skills dropped:            9 out of 27
Enter fullscreen mode Exit fullscreen mode

By turn 60, I am running with one-third of my skills invisible to the model. This explains the Thursday problem: I work in long sessions that build up history across a day. By late afternoon, the conversations are old enough that the history is large enough to squeeze the skill listing budget below half.

How to Tune It

The fix is straightforward. Add the setting to your config:

// ~/.claude/settings.json
{
  "skillListingBudgetFraction": 0.08
}
Enter fullscreen mode Exit fullscreen mode

That doubles the allocation from 4% to 8%. For a 147,600-token remaining budget, this gives 11,808 tokens for skill listings — enough for 53 skills at 220 tokens each. Even in a 60-turn session with 102,600 tokens remaining, you get 8,208 tokens, which covers 37 skills.

The tradeoff is real: those tokens come from somewhere. With skillListingBudgetFraction: 0.08, Claude Code will not exceed the fraction — it just has a larger ceiling. In practice, if you only have 27 skills, you will use 5,940 tokens per turn regardless of the fraction, because the listing only grows as large as the actual skill metadata requires. The fraction is a cap, not a target. Setting it higher does not cost you tokens if you do not have enough skills to fill the expanded budget.

The risk of setting it too high: in extremely long sessions with a large installed skill set, you could crowd out conversation history. I would not set it above 0.15 for most use cases. At 0.15, you are allocating 15% of remaining context to skill listings, which on a 100K remaining budget is 15,000 tokens — enough for 68 average-sized skills. Beyond that, you are trading meaningful context window for skills you probably do not need on every turn.

For project-level overrides where you know you are running a long, skill-intensive session:

// .claude/settings.json (project root)
{
  "skillListingBudgetFraction": 0.10
}
Enter fullscreen mode Exit fullscreen mode

Project-level config takes precedence over global. Use this when a specific project relies on many skills and tends toward long sessions.

Diagnostic Commands

Beyond the verbose logging approach, there are a few other ways to verify which skills are actually loading on a given turn.

The /skills command in a Claude Code session shows the current skill listing as Claude Code has assembled it for that turn:

/skills
Enter fullscreen mode Exit fullscreen mode

The output will enumerate every skill in the current listing. If you have 27 skills installed but only 11 appear in the /skills output, the missing 16 are not being injected into context. The model cannot see them.

Compare the /skills output against your installed skills directory:

# Count installed skills
ls ~/.claude/skills/ | wc -l

# Count listed skills (copy /skills output to a file, then count)
# They should match if your budget is sufficient
Enter fullscreen mode Exit fullscreen mode

For a more systematic check, I built a small diagnostic skill that logs when it loads. The skill has a very generic trigger (matches almost any message) and a body that simply outputs a timestamp and confirmation:

# ~/.claude/skills/budget-probe/SKILL.md
---
name: budget-probe
trigger: ".*"  # matches everything — use for diagnostics only, remove after
---

# Budget Probe

When this skill loads, output: "[PROBE LOADED at {timestamp}]" and nothing else.
Then continue with the user's original request normally.
Enter fullscreen mode Exit fullscreen mode

Install this at the bottom of your skill listing order (Claude Code lists skills alphabetically by default, so prefix the directory name with "z-" to force it last):

mv ~/.claude/skills/budget-probe ~/.claude/skills/z-budget-probe
Enter fullscreen mode Exit fullscreen mode

Now start a long session and watch for [PROBE LOADED] in responses. When it stops appearing, the budget has been exhausted to the point where even this last-in-order skill is being dropped. That is your signal that real skills are also being dropped.

Remove the probe after diagnosis — a generic trigger that matches everything is not something you want running permanently.

The Real Fix: Skill Hygiene

Increasing the fraction buys headroom, but it is not the complete answer. The better long-term solution is auditing your skills for bloat.

I went through my 27 skills after discovering this issue and found:

  • 4 skills I had not triggered in over a month. They were installed during experiments and never removed. Each one was consuming ~220 tokens per turn in the listing even though I never used them. Combined: 880 tokens per turn, every turn, for nothing.

  • 3 pairs of overlapping skills. I had separate skills for "commit message generation" and "git workflow automation" that had significant trigger overlap and partially redundant functionality. Merging each pair into a single skill reduced my listing size without losing capability.

  • 2 skills with verbose metadata. One skill had a 450-token description that could be reduced to 180 tokens without losing any meaningful instruction content. Another had lengthy parameter documentation that was more appropriate in the skill body than in the listing metadata.

After the audit: 27 skills became 18, average token size per skill dropped from 220 to 165, total listing size dropped from 5,940 tokens to 2,970 tokens. I cut the listing overhead by 50% without removing any capability I actually used.

Guidelines for skill hygiene:

Remove what you do not use. Run a 30-day audit. If you have not triggered a skill in 30 days, archive it to a separate directory outside the active skills path. You can restore it if you need it. Until then, it should not be consuming listing tokens.

Merge overlapping skills. Look for skills with similar trigger conditions. If two skills match similar inputs and accomplish related tasks, consider whether they can be one skill with a conditional internal path. Each merged skill saves ~200 tokens from the listing.

Trim metadata aggressively. The listing metadata should be a terse description for the model — just enough for it to know when to invoke the skill. Full documentation goes in the skill body. A skill name and a single-sentence trigger description is enough for most skills. That is 30-50 tokens, not 200.

Order skills by frequency of use. Claude Code loads skills in listing order and stops when the budget is exhausted. Skills at the top of the listing are loaded first. Put your most frequently used skills first. If you use graphify on 80% of sessions and use the budget-probe skill never, graphify should be listed first. Alphabetical ordering is a trap.

Claude Code does not currently expose a skill priority or ordering setting through the UI. The workaround is prefix naming: skills are listed alphabetically by directory name, so prefix your most important skills with "a-", "b-", etc. to force them to the top of the listing order.

# Rename high-priority skills to ensure they load first
mv ~/.claude/skills/graphify ~/.claude/skills/a-graphify
mv ~/.claude/skills/supabase-agent ~/.claude/skills/b-supabase-agent
mv ~/.claude/skills/cloudflare-mcp ~/.claude/skills/c-cloudflare-mcp
Enter fullscreen mode Exit fullscreen mode

Why This Matters for Hermes + Claude Code Skill Porting

I have been porting skills between Hermes and Claude Code as part of building out the WOWHOW automation stack. This issue is relevant to anyone doing the same.

Hermes has a different skill architecture. Hermes skills are loaded on-demand based on the active board configuration — they are not all listed in context simultaneously. The listing cost model is fundamentally different: Hermes pays the token cost of a skill only when it is dispatched, not on every turn.

Claude Code's model is: all eligible skills appear in the listing every turn, and the model decides which ones to invoke. This means you pay the token cost of the listing on every turn regardless of whether any skill is actually used. With 27 skills, you are spending ~5,940 tokens per turn describing skills even in turns where the model does nothing skill-related.

The implication for porting: you cannot dump 50 Hermes skills into Claude Code and expect the same behavior. The listing cost model penalizes breadth. In Claude Code, installing skills has a per-turn cost that accumulates across a session. In Hermes, skills have a near-zero per-turn cost unless actively dispatched.

If you are porting from Hermes to Claude Code:

  • Start with your 5-10 most critical skills only.

  • Verify the listing budget is sufficient for that set before adding more.

  • Use verbose logging to monitor actual listed skill counts in production sessions.

  • Add skills incrementally, checking the budget impact of each addition.

The token math is not optional. It is the constraint that determines whether your skills ecosystem is viable in Claude Code or just theoretically installed.

Version Note and Stability

I discovered this on Claude Code 2.1.129. The compiled default of 0.04 is what I found in that binary. Anthropic may change the default in future versions — either increasing it as model context windows grow, or documenting it formally. As of the time I am writing this (May 2026), it is undocumented in official release notes, changelog, and help output.

The setting key skillListingBudgetFraction is also not validated or constrained by Claude Code — you can set it to 0.5 or 1.0 and Claude Code will attempt to use that fraction. Setting it above 0.3 on context-heavy sessions is inadvisable. Setting it to 1.0 would attempt to allocate the entire remaining context to skill listings, which would crowd out everything else and produce incoherent model behavior. Stay in the 0.04–0.15 range for practical use.

The setting appears to be respected at the session level. Changing it in ~/.claude/settings.json takes effect on the next Claude Code session start, not mid-session. If you update it while a session is running, restart the session to see the new budget in effect.

My Current Configuration

After three weeks of diagnosis, audit, and tuning, here is what I am running:

// ~/.claude/settings.json
{
  "skillListingBudgetFraction": 0.08
}
Enter fullscreen mode Exit fullscreen mode
# Active skills (18 after audit, down from 27)
ls ~/.claude/skills/
a-graphify/
b-supabase-agent/
c-cloudflare-mcp/
d-blog-writer/
e-persistent-planner/
f-verification-agent/
g-figma-implement-design/
h-india-stack/
i-tool-builder/
j-new-product/
k-new-blog/
l-trust-boundary/
m-seo-audit/
n-deploy-check/
o-woocommerce-sync/
p-redis-inspector/
q-razorpay-webhook/
r-gsc-reporter/
Enter fullscreen mode Exit fullscreen mode

Average tokens per skill after metadata trimming: ~160. Total listing size: 18 × 160 = 2,880 tokens. At 0.08 fraction on a conversation with 100,000 tokens remaining, the budget is 8,000 tokens — room for 50 skills at 160 tokens each. I now have significant headroom in all but the most extreme sessions.

The Thursday problem is gone. Every skill loads on every turn. The /skills output matches my installed skill count. Verbose logging shows listed=18, dropped=0 even in sessions that run 80+ turns.

Summary

If your Claude Code skills are triggering inconsistently, especially in long sessions, skillListingBudgetFraction is almost certainly the cause. The diagnostic steps are:

  1. Run claude --verbose and look for the [skills] budget=... listed=... dropped=... line.

  2. If dropped is greater than zero, you are hitting the budget cap.

  3. Add "skillListingBudgetFraction": 0.08 to ~/.claude/settings.json as a first fix.

  4. Run a skill audit: remove unused skills, merge overlapping ones, trim verbose metadata.

  5. Prefix-name your most critical skills to ensure they are listed first.

The setting exists. The default is conservative. It is not documented. Now you know about it.

Originally published at wowhow.cloud

Top comments (0)