[BUG] Cowork: skill scripts silently truncated on disk at a token boundary, passing py_compile and becoming canonical
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?
[BUG] Cowork: skill scripts silently truncated on disk at a token boundary, passing py_compile and becoming canonical
Related but distinct from #41702 (OneDrive-backed workspaces silently truncate files on write). #41702 covers the write path on OneDrive-synced folders. This report adds: (a) the truncation also occurs on a folder under C:\Users\Public\Documents (not a OneDrive user-profile path), (b) the clip lands on a syntactically valid token boundary so py_compile reports OK and the gutted file silently becomes the canonical version, and (c) a read-coherence symptom where different POSIX tools and a Python open().read() initially disagreed on file length within the same session.
Environment
- Product: Claude desktop app — Cowork mode (research preview)
- OS: Windows 11
- App package:
Claude_pzs8sxrjxfjjc(MSIX/packaged app) - Sandbox mount: virtiofs (
fuse,default_permissions,allow_other) exposing Windows paths to the Linux sandbox - Skills execute from a read-only mount:
AppData\Local\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\Claude\local-agent-mode-sessions\skills-plugin\...\skills - User-editable skill scripts live separately in a read-write mounted workspace folder:
C:\Users\Public\Documents\...\Skills\
Summary
A skill helper script (apply_krt_updates.py) was found truncated on disk: 24,378 bytes / 599 lines, ending mid-identifier:
new_rows, row_updates, wish_list, wish_list_updates, trip_rows, neg
The complete, correct version is 26,341 bytes / 652 lines and ends normally with if __name__ == '__main__': main(). The truncation dropped the back half of a feature (8 of 14 expected references to the affected code path remained). The file's mtime was stable at the time of an earlier save (no later write recorded), and md5sum was stable across repeated reads — i.e., this is a persisted, on-disk truncation, not a transient read glitch.
Why this is dangerous (and why it evaded detection)
- The clip landed on a valid token boundary. The leftover
a, b, c, negis a syntactically legal Python tuple-expression statement.python -m py_compiletherefore returns success on the truncated file. Any workflow relying on "compile check after edit" gets a false pass. - The truncated version becomes canonical. Subsequent sessions read the clipped file as the source of truth and run it with missing logic, producing silent wrong behavior rather than an error.
- Two-copy architecture amplifies it. Skills run from a read-only installed copy while edits happen to a separate writable source copy; the source→install step is a non-atomic copy that can be interrupted, and there is no post-install size/checksum verification.
Read-coherence observation
Within a single sandbox session, an earlier py_compile of the same path succeeded while wc/tail/md5sum reported the truncated 24,378-byte content; a later python3 open(p,'rb').read() also returned 24,378 bytes. The combination suggests the Windows↔virtiofs boundary can briefly serve inconsistent views of a file whose backing store was modified by a host-side process, in addition to the persisted truncation itself.
Steps to reproduce (observed)
- Edit a skill helper
.pyin a Cowork-mounted Windows folder so the file grows. - Save / let the host-side sync or install step write the file.
- Observe the on-disk file clipped to roughly its previous length, ending mid-content but on a token boundary.
- Run
python -m py_compile <file>→ reports OK despite the truncation.
Expected
File writes are atomic and complete; a partial write fails loudly rather than persisting a clipped file that passes a syntax check.
Actual
File is silently truncated mid-content, still parses, and becomes the canonical version used by the skill.
Impact
Skills run with partial logic and produce incorrect results with no error surfaced. The standard verification (py_compile) cannot detect this class of truncation.
Suggested mitigations
- Atomic write-temp-then-rename for both the user-edit save path and the source→install copy path.
- Post-write/post-install verification by byte length + checksum against the source, not syntax compilation.
- Surface a hard error when a write's resulting size is smaller than the bytes intended to be written.
- Document that cloud-synced / on-demand / packaged-app-redirected folders are unsafe as Cowork skill source locations, and recommend a plain local non-synced path.
Notes
- Folder involved is under
C:\Users\Public\Documents(not a OneDrive user-profile Known Folder), which suggests the trigger is broader than OneDrive Known Folder Move alone.
What Should Happen?
File writes are atomic and complete; a partial write fails loudly rather than persisting a clipped file that passes a syntax check.
Error Messages/Logs
Steps to Reproduce
Steps to reproduce (observed)
Edit a skill helper .py in a Cowork-mounted Windows folder so the file grows.
Save / let the host-side sync or install step write the file.
Observe the on-disk file clipped to roughly its previous length, ending mid-content but on a token boundary.
Run python -m py_compile <file> → reports OK despite the truncation.
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
Claude 1.9659.2 (390d6c) 2026-05-28T21:50:01.000Z
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
Other
Additional Information
Using Claude Desktop.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗