anthropics / anthropics/claude-code
[BUG] Cowork: publishing an artifact silently stops updating its local copy in ~/Claude/Artifacts, and the directory mtime hides it
- Lenguaje dominante
- Python
- Estrellas
- 145k
- Forks
- 23.1k
- Métricas de merge de PR
- Métricas de PR pendientes
Descripción
# [BUG] Cowork: publishing an artifact silently stops updating its local copy in `~/Claude/Artifacts`, and the directory mtime hides it
### Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report
- [x] I am using the latest version
### What's Wrong?
Cowork keeps a local copy of each artifact at `/Artifacts//index.html` — `~/Claude/Artifacts/...` on my machine (the folder is configurable, so it is not always under `~/Documents`). Historically that file *was* the artifact.
After an artifact is published to the hosted system and gets a `claude.ai/code/artifact/{uuid}` URL, **the hosted page keeps updating but the local `index.html` is never written again.** The local file silently freezes at whatever it contained at migration time.
The reason this is worse than a plain stale-cache bug: **the directory's mtime keeps moving.** `thumbnail.png` and `debug.jsonl` inside each slug folder are rewritten regularly, so `ls -la ~/Claude/Artifacts/` shows every artifact as freshly modified. Anything that checks the folder — a skill, an export step, a scheduled task, or a person eyeballing timestamps — concludes the mirror is live. It isn't. You have to stat `index.html` specifically to see the truth.
So the failure is silent in both directions: no error, and the most obvious freshness check actively reports the wrong answer.
### Evidence
Captured 2026-09-02. Directory mtime vs the `index.html` inside it:
| slug | directory mtime | `index.html` mtime | has hosted UUID |
|---|---|---|---|
| skills-galaxy | 2026-09-02 19:45 | **2026-07-28 18:48** | yes — hosted updated 2026-09-02 |
| mama-studios-dashboard | 2026-09-02 21:36 | **2026-09-01 09:48** | yes — hosted updated 2026-09-02 |
| jump-studios-dashboard | 2026-09-02 21:35 | **2026-08-27 19:39** | yes — hosted updated 2026-09-02 |
| parkville-dashboard | 2026-09-02 21:35 | **2026-08-03 09:56** | yes |
| morning-dashboard | 2026-09-02 21:35 | **2026-06-23 13:58** | no |
| wedding-tracker | 2026-09-02 21:35 | 2026-08-30 20:26 | no |
| isa-position-tracker | 2026-09-02 19:45 | 2026-09-02 19:44 | no |
| cash-deployment-plan-2026 | 2026-08-17 12:23 | 2026-08-02 11:46 | no |
| mama-studios-rate-card | 2026-08-12 13:24 | 2026-08-11 21:44 | no |
Note the pattern: **every slug with a hosted UUID has a frozen `index.html`; the one that is still written locally (`isa-position-tracker`, updated today at 19:44) is one that never migrated.** Five directories were bumped to 21:35–21:36 while their `index.html` files stayed weeks or months old.
Content proof that the two really have diverged, not just their timestamps — `skills-galaxy`:
- **Hosted** (fetched today): contains `"taken": "2026-09-02"`, `"totals": {"skills": 152, "plugins": 17, ...}`, and a log entry dated `2026-09-02` reading *"Baseline re-established."*
- **Local** `index.html`: 29,152 bytes, `grep -c "2026-09"` returns **0**. It has no 2026-09 content at all and is structurally an earlier generation of the same page.
Same artifact, same slug, five weeks apart.
### Steps to Reproduce
1. Have a Cowork artifact that exists both as a local slug folder and as a hosted `claude.ai/code/artifact/{uuid}` page.
2. In Cowork, update the artifact and publish it. Confirm the hosted page shows the new content.
3. `stat -f '%Sm' ~/Claude/Artifacts//index.html` → **unchanged**, still pre-migration.
4. `stat -f '%Sm' ~/Claude/Artifacts//` → **current timestamp**, because `thumbnail.png` / `debug.jsonl` were rewritten.
5. Diff the local `index.html` against the hosted page — they differ, with no warning anywhere.
### Expected Behaviour
One of:
- **Keep mirroring.** Publishing writes the published HTML back to `index.html` (and ideally appends to `versions/`), so the local folder stays a true mirror; or
- **Mark it dead.** If the local folder is now an archive by design, make that explicit — move migrated slugs to an `Archive/` subfolder, write a `MIGRATED` marker with the artifact UUID, or stop rewriting `thumbnail.png`/`debug.jsonl` inside frozen folders so the directory mtime stops lying.
Either is fine. The current state — a folder that looks live, is named like it's live, and is silently months out of date — is the worst of both.
### Impact
Any automation pointed at `~/Claude/Artifacts//index.html` reads stale content and reports success. In my case that spans several skills and scheduled tasks that treat the local folder as the artifact's source of truth. There is no error, no warning, and the natural freshness check (directory mtime) returns a fresh-looking answer.
This also makes a published artifact effectively unreadable from Cowork, since the URL route doesn't work either — filed separately.
### Possible Mechanism (inference — not verified, treat with suspicion)
Two generations of artifact system appear to coexist: a local-first one (slug directory + `index.html` + `versions/`, written via the older `update_artifact(html_path, id)` tooling) and the current hosted one (the `Artifact` tool uploads to claude.ai, which assigns the UUID and keeps server-side version history). Publishing through the current tool looks like it has no write-back leg to the local folder, while thumbnail/preview generation still touches the directory. The split in the table above — migrated frozen, unmigrated live — is consistent with that, but I have not confirmed it in the code and may be wrong about the cause. The observable behaviour in the table and the content diff stand on their own.
Possibly related: #91604 reports existing Live Artifacts becoming effectively read-only after the same late-August migration window.
### Environment
- macOS (Apple Silicon), Darwin 25.5.0
- Claude Desktop 1.44121.1
- Bundled Claude Code SDK 2.1.258
- Individual paid subscription
- Cowork user files path is configurable (`coworkUserFilesPath`); written as `~/Claude/Artifacts/...` above rather than assuming `~/Documents`
Guía de contribución
No hay ninguna guía de contribución indexada para este repositorio
Línea de trabajo
Start by tracing the Cowork publishing path from the `Artifact` tool and the older `update_artifact(html_path, id)` tooling, using a migrated slug's `index.html`, `thumbnail.png`, and `debug.jsonl` as the observed outputs. Reproduce the publish/update sequence and compare local `index.html` timestamps and content with the hosted artifact. Done means migrated artifacts either continue mirroring into `index.html` or are explicitly marked as archived without misleading directory freshness.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- macos, python
- Área
- cloud, desktop
- Tipo de issue
- Error
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Estado de actividad
- Activo
- Claridad
- Bastante claro
- Aptitud para principiantes
- 42/100