Skip to content

[Bug]: Startup migration exits on "database is locked" instead of waiting, so a CLI holding statev2.sqlite crash-loops the desktop backend #21736

Closed as not planned

Description

@westline-jordan

What happened

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).

Activity

  1. juliusmarminge commented on Oct 19, 2026

    @juliusmarminge
    Member

    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 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.

    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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementRequested improvement or new capability.via-triageFiled through npx t3 triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions