[BUG] Skill Delivery
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Installed skill renders as v2 in Settings but is delivered to sessions as v1
Product: Claude desktop (Cowork / local agent mode), macOS 15.6 (Darwin 25.6.0)
Date observed: 2026-09-21 / 2026-09-22
Severity: Silent wrong-output. Runs complete normally, exit 0, and produce incorrect data.
Summary
A user skill was updated and installed. Settings → Skills → Contents renders the new
version. Every session is delivered the previous version. Nothing reports an error at
any point — the stale code runs to completion and writes wrong values.
Reproduced across 5+ fresh sessions, 3 reinstalls, multiple full app restarts, and a
complete quarantine-and-rebuild of the plugin cache.
The skill
star-tribune-daily-download, a user-installed skill (~2.1 MB unpacked, 27 files;SKILL.md 527 KB, scripts/extract_notices.py 809 KB).
- Previous build:
2026-0917b - New build:
2026-0921a— widens one regex,_PROPERTY_ADDRESS_LABEL_RE name:anddescription:are byte-identical between the two builds. Only the
body of SKILL.md and scripts/extract_notices.py differ.
What Settings shows
Settings → Skills → star-tribune-daily-download → Contents renders:
name: star-tribune-daily-download
version: 2026-0921a
description: Receive today's Star Tribune eEdition ...
---
<!-- build: 2026-0921a
What sessions receive
/var/folders/xw/.../T/claude-hostloop-plugins/a40ffb98fbcc885b/
<project-uuid>/skills/star-tribune-daily-download/SKILL.md
-> version: 2026-0917b
Content check, not a version-string check:
| | _PROPERTY_ADDRESS_LABEL_RE occurrences |
|---|---|
| 0921a bundle (authoritative) | 3 |
| delivered to sessions | 0 |
SCRIPT_VERSION in the delivered extract_notices.py is "0917b"; in the bundle it is"0921a". Unpacked byte total of the delivered tree is 2,090,745 — an exact match for
the 0917b bundle. The delivery is a complete, intact previous version, not a truncated
or partially-written one.
Where the new version actually lives
~/Library/Application Support/Claude/:
grep -rl "_PROPERTY_ADDRESS_LABEL_RE" .
-> ./IndexedDB/https_claude.ai_0.indexeddb.leveldb/000716.log
IndexedDB is the only skill store on the machine. Occurrence counts in that single log
file:
2026-0921a x21 (~3 records; the skill was installed 3 times)
2026-0917b x2 (fragments; a full 0917b record would carry 11)
So the store holds the new version and shows no evidence of a competing stale record.
The /var/folders tree is a materialization of that store, and the materialization
emits the old version.
Rebuild does not fix it — this is the key fact
The plugin cache directory was quarantined with the app closed:
mv a40ffb98fbcc885b a40ffb98fbcc885b.quarantine-20260922-1019
On relaunch the app created a new directory with the same hash name:
drwx------ 3 Sep 22 10:20 a40ffb98fbcc885b
drwx------ 3 Sep 5 21:54 a40ffb98fbcc885b.quarantine-20260922-1019
a40ffb98fbcc885b/<project-uuid>/skills/star-tribune-daily-download/SKILL.md
-> version: 2026-0917b <-- freshly built, still stale
a40ffb98fbcc885b.quarantine-.../.../SKILL.md
-> version: 2026-0917b
Built from scratch, deterministic same hash, same stale content. The materializer is
resolving to 0917b from a store that contains 0921a.
Directory shape (may be relevant)
claude-hostloop-plugins/ holds 349 entries. 348 are symlinks to per-session .claude
directories, which contain backups/ cache/ policy-limits.json/ projects/ sessions/ and
no skills/. Exactly one entry is a real directory — a40ffb98fbcc885b — and it is
the only skills tree that exists. Its original mtime was 2026-09-05, sixteen days older
than anything else in the folder.
Individual skills inside it retain their own install mtimes (Sep 15, Sep 16, Sep 18),
so the tree is updated in place per skill rather than replaced. On 2026-09-22 at 07:34
the star-tribune-daily-download subdirectory mtime moved — the updater ran and wrote
0917b.
Reproduction
- Install a skill whose
nameanddescriptionare unchanged from the installed
version but whose SKILL.md body and bundled scripts differ.
- Confirm Settings → Skills → Contents renders the new
version:. - In a fresh session, read the skill's own files from the runtime skills directory.
- Observe the previous version's content.
Things ruled out
- Bad bundle. Unpacked and verified: the bundle carries the new regex and the new
SCRIPT_VERSION.
- Upload never completed. Settings renders the new version; installed 3 times.
- Size / truncation. New build is 809,304 B vs 805,225 B for the old one, unpacked
totals 2,096,354 vs 2,090,745. The older, smaller-by-5 KB build installed fine, and
the delivered tree is byte-complete.
- Cache reuse keyed on name/description. Another skill (
abstract-probate) updated
successfully on 2026-09-18 with a byte-identical description.
- Stale LevelDB table. Both version strings appear in the same current
.logfile;
there is no older .ldb involved.
- Stale cache directory. Quarantined and rebuilt; the rebuild reproduced it.
Impact
Two newspaper editions were processed with the old regex and silently lost 35 property
addresses that the new build extracts correctly. The run reported success. The only
signal was a version string in the output metadata, which was accurate about what ran
and therefore indistinguishable from a correct run unless independently compared against
the bundle.
A user cannot detect this from the UI: Settings shows the new version, the run exits 0,
and the output looks well-formed.
Current workaround
Unpack the .skill bundle to a user-controlled path and invoke the scripts from there
rather than from the skill directory. This bypasses delivery entirely for code, but theSKILL.md instructions a session loads still come from the stale copy.
What Should Happen?
A skill installed via Settings should be delivered to sessions at the version Settings displays — the materialized skill cache must reflect the installed build, or the run must fail loudly rather than silently execute the previous version.
Error Messages/Logs
Steps to Reproduce
Install a user skill. Note its build (e.g. version: 2026-0917b in SKILL.md frontmatter).
Edit the skill so that SKILL.md body and a bundled script change, but name: and description: stay byte-identical. Bump version: (e.g. 2026-0921a) and add a uniquely greppable token to the script.
Repackage as .skill and install it via Settings → Skills (upload-replace).
Confirm Settings → Skills → skill → Contents renders the new version:.
Fully quit and relaunch the app. Start a fresh session.
In that session, read the skill's own files from the runtime skills directory — /var/folders/.../T/claude-hostloop-plugins/<hash>/<project-uuid>/skills/<skill>/.
Observed: SKILL.md reports the old version:, and the unique token from step 2 is absent from the script. The delivered tree is a byte-complete copy of the previous build.
Repeat steps 3–6 twice more, and additionally quit the app and mv the <hash> directory aside before relaunching. The app recreates it under the same hash name and still populates it with the old build.
Verify by content, not by version string — grep the unique token from step 2. The version string and the code are stale together, so they agree with each other and a version check alone looks correct.
Claude Model
Opus
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
Claude 2.2553.1 (c38127) 2026-09-18T00:41:58.000Z
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
_No response_