[BUG] Skill Delivery

Status Open
Maintainer reply None cached
Activity 0 comments · opened Sep 22, 2026

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: and description: 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

  1. Install a skill whose name and description are unchanged from the installed

version but whose SKILL.md body and bundled scripts differ.

  1. Confirm Settings → Skills → Contents renders the new version:.
  2. In a fresh session, read the skill's own files from the runtime skills directory.
  3. 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 .log file;

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 the
SKILL.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_

View original on GitHub ↗