[BUG] SQLite writes fail on connected-folder mount (disk I/O error / database is locked); failed writes leave stray journal/lock artifacts
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?
Running normal SQLite3 write operations (INSERT, CREATE TABLE IF NOT EXISTS, commit) against a .db file that lives inside a Cowork connected folder fails consistently with sqlite3.OperationalError: disk I/O error.
This happens whether the write is issued from device_bash (running locally on the user's own machine, per its tool description) or from the cloud-container Bash tool — same failure either way, so it appears tied to the connected-folder mount itself, not the local/cloud split.
Switching the connection to SQLite's unix-dotfile locking mode (file:path?vfs=unix-dotfile) lets reads succeed, but writes still fail — either the same disk I/O error on insert/commit, or "database is locked" on a subsequent PRAGMA call.
Worse, a failed write is not a clean no-op: it left a stray rollback-journal file (<db>-journal) and a stray lock artifact (<db>.lock, created as a directory under unix-dotfile mode) sitting next to the live database. In one reproduction a partially-committed write also left a stray table behind in the actual database file. None of this could be cleaned up until the session explicitly called device_request_delete_permission and the user approved deletion for the whole connected folder — i.e., recovering from a failed write required an extra permission grant just to remove debris the platform's own failed operation created.
This looks like it may share a root cause with #55206 (bash sandbox can create files on a mounted host folder but unlink is denied, breaking git's lock-file cleanup) — that issue documents the mount denying unlink() until delete permission is granted, which matches why the stray SQLite journal/lock files couldn't be removed. But the SQLite case also shows a distinct failure — disk I/O error during an active write/commit, before any cleanup is attempted — which looks like the mount not honoring POSIX advisory (fcntl) locking, not just denying unlink.
What Should Happen?
Either: (1) SQLite reads and writes against a file inside a connected folder should work the same as a genuinely local path — the mount should transparently support the locking/journaling primitives SQLite needs; or (2) if the mount technology can't support that, a write should fail atomically and cleanly, with no orphaned -journal or .lock files/directories and no partially-committed tables, so recovering never requires a delete-permission round-trip.
Error Messages/Logs
sqlite3.OperationalError: disk I/O error
(raised from either conn.execute(...) or conn.commit(), depending on when SQLite needs to touch its journal file)
With vfs=unix-dotfile:
sqlite3.OperationalError: disk I/O error
sqlite3.OperationalError: database is locked
Steps to Reproduce
- Connect a folder to a Cowork session that contains (or will contain) a SQLite3 .db file.
- 2. From device_bash, cd into the mounted folder (e.g. $HOME/mnt/<folder-name>) and run:
- ```python
- import sqlite3
- conn = sqlite3.connect("some_file.db")
- conn.execute("INSERT INTO some_table (...) VALUES (...)")
- conn.commit()
- ```
- 3. Observe: sqlite3.OperationalError: disk I/O error (can occur on the execute or the commit).
- 4. Retry using the unix-dotfile VFS:
- ```python
- sqlite3.connect("file:some_file.db?vfs=unix-dotfile", uri=True)
- ```
- Reads succeed; writes still fail with disk I/O error or database is locked.
- 5. ls the folder afterward — a stray <db>-journal file and/or <db>.lock directory remain next to the real .db file.
- 6. Copy the same .db file to a path outside the mount (e.g. the device_bash VM's own home directory, not under $HOME/mnt/...) and repeat step 2 there — it succeeds every time. Copying the result back over the mounted path with a plain cp also succeeds every time.
Claude Model
None
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
N/A — Cowork desktop app session (not the Claude Code CLI)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Other
Additional Information
Note: this happened inside Claude (Cowork) with a connected local folder — via the mcp__remote-devices__* device bridge / device_bash, not the Claude Code CLI in a real terminal. That's why the CLI-specific fields above don't cleanly apply.
Environment: Claude (Cowork), session linked to a local Mac via the Claude desktop app (connected folder / device bridge feature). Connected folder mounted into the session at $HOME/mnt/<folder-name>. Target file: a small (~12-16 KB) SQLite3 database, accessed via Python's stdlib sqlite3 module. Reproduced identically via device_bash (runs locally on the user's machine) and the cloud-container Bash tool.
Possibly related: #55206 (same connected-folder mount denying unlink(), observed via git lock files instead of SQLite).