You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug]: Startup migration exits on "database is locked" instead of waiting, so a CLI holding statev2.sqlite crash-loops the desktop backend #21736
After T3 Code Nightly updated itself (0.1.1-nightly.20261016.3218 → 0.1.1-nightly.20261019.3360, macOS), the desktop backend child exited with code 1 roughly every 17 s for ~17 minutes. Each start failed in runMigrations → reconcileV2PreviewMigration:
effect/sql/SqlError: Failed to execute statement
at reconcileV2PreviewMigration
at runMigrations
[cause]: effect/sql/SqlError/LockTimeoutError: Failed to execute statement
[cause]: Error: database is locked
The lock holder was a t3 CLI process (the npm-installed t3 package, still on the previous nightly) running t3 auth session issue --base-dir ~/.t3 from a local automation. It kept userdata/statev2.sqlite open for several minutes (the database is ~58 GiB, 19.6 GiB reclaimable per t3 doctor; see #21154). The backend recovered within seconds once that process exited and the CLI was updated to the app's version.
Expected
The startup migration should wait/retry for the lock (or report "database in use by pid N") rather than exit after busy_timeout (5 s) and get restarted in a tight loop.
A CLI that is older than the database's schema should refuse to open it (or exit fast) rather than hold it while a newer server migrates.
Why the versions drifted
The in-app updater replaces the app bundle but not an npm-installed t3 CLI, so any tooling that calls the npm t3 (e.g. t3 auth session issue for the HTTP API) is a version behind until someone reinstalls it. ~/.t3/bin/t3 (the wrapper the app writes) doesn't have this problem; documenting it as the recommended CLI for scripts, or having the npm package defer to it when present, would avoid the skew.
Environment
macOS 26 (Darwin 25.6), Apple silicon
T3 Code (Nightly) 0.1.1-nightly.20261019.3360, Orchestrator V2
Related: #21154 (event store growth), #5099 (busy_timeout, closed).
Thanks for tracing this. I don't think there's a startup bug to track here.
Every CLI command that opens the database goes through the same startup as the server, and that includes t3 auth session issue (apps/server/src/auth/EnvironmentAuth.ts:1372-1376, apps/server/src/persistence/Sqlite.ts:39). Builds before #21122 also ran PRAGMA optimize there. On a 58 GiB database that can hold the write lock for minutes, and #21122 removed it (Sqlite.ts:40-50). That fits what you saw: it cleared once the CLI matched the app.
The migration already waits for the write lock like every other write. It uses BEGIN IMMEDIATE with a 5 second busy timeout (packages/shared/src/nodeSqliteClient.ts:818, Sqlite.ts:18). The desktop restarts the backend with a backoff capped at 10 seconds (apps/desktop/src/backend/DesktopBackendManager.ts:34-35, :289-290). Both are intended.
Activity
juliusmarminge commentedon Oct 19, 2026
Note
Grok responding on behalf of Julius.
Thanks for tracing this. I don't think there's a startup bug to track here.
Every CLI command that opens the database goes through the same startup as the server, and that includes
t3 auth session issue(apps/server/src/auth/EnvironmentAuth.ts:1372-1376,apps/server/src/persistence/Sqlite.ts:39). Builds before #21122 also ranPRAGMA optimizethere. On a 58 GiB database that can hold the write lock for minutes, and #21122 removed it (Sqlite.ts:40-50). That fits what you saw: it cleared once the CLI matched the app.The migration already waits for the write lock like every other write. It uses
BEGIN IMMEDIATEwith a 5 second busy timeout (packages/shared/src/nodeSqliteClient.ts:818,Sqlite.ts:18). The desktop restarts the backend with a backoff capped at 10 seconds (apps/desktop/src/backend/DesktopBackendManager.ts:34-35,:289-290). Both are intended.Making an older CLI refuse a newer schema, waiting longer at startup, or having the npm CLI defer to the app's wrapper would be new behavior. Please open an Idea for those: https://github.com/pingdotgg/t3code/discussions/new?category=ideas