pingdotgg / pingdotgg/t3code

[Bug]: Overlapping server lifecycles during a restart leave state.sqlite malformed and make the app unusable

Open
#11,084 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug via-triage
Dominant language
TypeScript
Stars
23k
Forks
5.9k
Avg merge
11h 14m
Merged PRs (30d)
357

Description

Before submitting
  • I searched existing issues and did not find an exact duplicate.
  • I included the observed errors and server timeline.
Area

apps/server / persistence / server lifecycle

Summary

The T3 Code server initialized a new server lifecycle while an existing Cursor-backed turn was still producing and persisting activity.

The traces show that the new lifecycle began opening and writing to the same state.sqlite database before activity from the previous lifecycle had stopped.

Within approximately one second, SQLite began returning:

SQLITE(11) database disk image is malformed

The error now occurs in both the thread that was active during the restart and newly created threads. T3 Code can no longer append orchestration events, making the application unusable.

Observed timeline

Times below are UTC.

  • 13:41:13.065 — a Cursor-backed turn starts.
  • 13:44:30.039 — a new server initialization begins.
  • 13:44:30.052 — the new lifecycle opens state.sqlite.
  • 13:44:30.065 — it executes PRAGMA journal_mode = WAL.
  • 13:44:30.218 — activity from the previously running turn is still inserted into orchestration_events.
  • 13:44:30.238 — another activity append from the existing turn completes.
  • 13:44:30.377–13:44:30.390 — additional activity from the existing turn is still persisted.
  • 13:44:30.608 — the newly initialized server begins listening on port 3773.
  • 13:44:30.691 — the new lifecycle inserts an orchestration event.
  • 13:44:30.777 — startup session reconciliation records the previously active provider session as no longer available.
  • 13:44:30.888 — the new server reports startup success.
  • 13:44:31.122 — server queries begin failing with SQLITE(11) database disk image is malformed.

The previous and new server lifecycles therefore performed overlapping database activity during the restart window.

Restart context

The outer npx t3 process remained alive throughout the event. Its operating-system start time did not change.

The installed T3 Code version before and after the observed restart was 0.0.40. No server-update request or version change appears in the available server traces immediately before the new startup.

The logs confirm that a new internal server lifecycle started, but they do not expose what triggered that lifecycle restart.

Provider-session result

During startup reconciliation, the active turn was finalized with:

Provider session did not survive a server restart. Send a new message to continue.

The persisted provider runtime subsequently showed the Cursor session as stopped and the affected turn as completed with an error.

User-visible error

Attempting to stop or interact with the affected thread produces:

SQL error in OrchestrationEventStore.append:insert: SQLITE(11) database disk image is malformed

Creating a new thread and attempting to send its first message produces the same error:

SQL error in OrchestrationEventStore.append:insert: SQLITE(11) database disk image is malformed

The failure is therefore not limited to the turn that was active during the restart.

Database integrity

Read-only SQLite checks do not return ok.

Both PRAGMA quick_check and PRAGMA integrity_check report structural corruption, including:

  • database pages referenced more than once;
  • an orchestration event row ID reported out of order;
  • btreeInitPage() returning error code 11;
  • corruption involving the orchestration event table and its indexes.
Expected behavior

Restarting or reinitializing the server should not corrupt persisted state.

After a restart, existing threads should enter a recoverable state, and new threads should remain usable.

Actual behavior

The server database is structurally malformed.

All attempts to append new orchestration events fail, including attempts made from newly created threads. Existing and new agent work can no longer be started or continued.

Reproduction status

This was observed in a live remote-server session.

The exact action that triggered the internal server lifecycle restart has not yet been identified. The available traces establish the overlapping database activity and the first corruption errors, but do not contain the initiating restart event.

Environment
  • T3 Code 0.0.40
  • T3 Code Alpha desktop client on macOS
  • Remote T3 Code server on Linux
  • T3 Connect
  • Cursor provider
  • Local checkout mode
Impact

Blocks all agent work in the affected T3 Code environment.

Related issues
  • #961 — Persisted state corruption can leave T3 Code unusable with no clear recovery path
  • #6097 — Multiple server runtimes can access the same T3 Code database

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in apps/server persistence and server-lifecycle code, using the reported startup timeline and related issues #961 and #6097 as context. Trace what initiates a new lifecycle while an existing turn is writing to state.sqlite, then verify with SQLite quick_check and integrity_check. Done means restarts do not corrupt persisted state and both existing and new threads remain usable.

Written by the indexing model from the issue text.

Assessment

Tech stack
sqlite, typescript
Domain
backend, database
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.