Skip to content

Unhandled SQLITE_FULL crash kills process when disk is full during session #17589

@coygeek

Description

@coygeek

Description

OpenCode crashes with an unhandled SQLiteError: database or disk is full (errno 13, SQLITE_FULL) when the host disk runs out of space during a session. The error terminates the process immediately with no graceful degradation, no user-facing warning, and no opportunity to save in-progress work.

The crash occurs in the updatePart hot path (packages/opencode/src/session/index.ts), which calls Database.use() to upsert into PartTable. The Database.use() wrapper (packages/opencode/src/storage/db.ts) only catches Context.NotFound errors, re-throwing everything else. SQLite storage errors like SQLITE_FULL propagate uncaught and kill the process.

This is distinct from #7607 (JSON-era session corruption after disk-full). The current issue affects the SQLite-based storage layer introduced after that era.

Root cause in code:

Database.use() in packages/opencode/src/storage/db.ts:

export function use<T>(callback: (trx: TxOrDb) => T): T {
    try {
      return callback(ctx.use().tx)
    } catch (err) {
      if (err instanceof Context.NotFound) {
        // ... handle missing context
      }
      throw err  // <-- SQLITE_FULL lands here, unhandled
    }
  }

Every session write operation (updatePart, updateMessage, create) passes through this wrapper with no storage-error handling. The JsonMigration.insert() function does wrap its inserts in try/catch, showing the pattern is known but inconsistently applied to the hot path.

Affected write sites (no error handling around .run()):

Function Operation File
updatePart PartTable.insert().onConflictDoUpdate().run() src/session/index.ts
updateMessage MessageTable.insert().onConflictDoUpdate().run() src/session/index.ts
create SessionTable.insert().values().run() src/session/index.ts
remove SessionTable.delete().run() src/session/index.ts

OpenCode version

1.2.24 (crash observed 2026-03-15)

Steps to reproduce

  1. Start an OpenCode session with a long-running agent task (e.g., opencode run -m github-copilot/gpt-5.4 "..." with multiple rounds of subagent work)
  2. Allow disk space to fill up during the session (e.g., from concurrent builds, large downloads, or OpenCode's own session storage growth)
  3. When OpenCode next attempts to persist a message part, the process crashes immediately

Crash output:

Error: SQLiteError: database or disk is full
756 |           session_id: sessionID,
757 |           time_created: time,
758 |           data,
759 |         })
760 |         .onConflictDoUpdate({ target: PartTable.id, set: { data } })
761 |         .run()
               ^
SQLiteError: database or disk is full
      errno: 13,
 byteOffset: -1,
       code: "SQLITE_FULL"

      at #run (bun:sqlite:185:20)
      at <anonymous> (src/session/index.ts:761:10)
      at run (node:async_hooks:62:22)
      at use (src/storage/db.ts:140:28)
      at <anonymous> (src/session/index.ts:751:14)

Operating System

macOS (Darwin 25.3.0)

Metadata

Metadata

Assignees

Labels

coreAnything pertaining to core functionality of the application (opencode server stuff)

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions