{"record":{"id":"c5a878f2d18e0779","repo":"benbjohnson/litestream","slug":"begin-w","errorCode":null,"errorMessage":"begin: %w","messagePattern":"begin: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"db.go","lineNumber":2592,"sourceCode":"\tif mode != CheckpointModeTruncate && walFrameN <= preCheckpointFrameN {\n\t\tresult, err = db.verifyAndSyncWithExecutor(ctx, true, exec, 0)\n\t\tif err != nil {\n\t\t\treturn false, fmt.Errorf(\"cannot copy wal after checkpoint: %w\", err)\n\t\t}\n\t\texec.applySyncResult(result)\n\t\texec.state.syncedSinceCheckpoint = false\n\t\treturn true, nil\n\t}\n\n\t// Start a transaction. This will be promoted immediately after.\n\tdb.setSyncDiagPhase(diagPhaseCheckpointSnapshotBoundaryLock,\n\t\tfunc(s *diagState) {\n\t\t\ts.checkpointMode = mode\n\t\t\ts.lastSyncedWALOffset = exec.state.lastSyncedWALOffset\n\t\t})\n\ttx, err := db.db.BeginTx(ctx, nil)\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"begin: %w\", err)\n\t}\n\tdefer func() { _ = rollback(tx) }()\n\n\t// Insert into the lock table to promote to a write tx. The lock table\n\t// insert will never actually occur because our tx will be rolled back,\n\t// however, it will ensure our tx grabs the write lock. Unfortunately,\n\t// we can't call \"BEGIN IMMEDIATE\" as we are already in a transaction.\n\tif _, err := tx.ExecContext(ctx, `INSERT INTO _litestream_lock (id) VALUES (1);`); err != nil {\n\t\treturn false, fmt.Errorf(\"_litestream_lock: %w\", err)\n\t}\n\n\t// Copy anything that may have occurred after the checkpoint.\n\tdb.setSyncDiagPhase(diagPhaseCheckpointSnapshotBoundary,\n\t\tfunc(s *diagState) {\n\t\t\ts.checkpointMode = mode\n\t\t\ts.lastSyncedWALOffset = exec.state.lastSyncedWALOffset\n\t\t})\n\tsnapshotInfo := syncInfo{","sourceCodeStart":2574,"sourceCodeEnd":2610,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/db.go#L2574-L2610","documentation":"To take a boundary snapshot at the end of a checkpoint, Litestream begins a transaction (BeginTx) that it will later promote to a write transaction via a lock-table insert. This error wraps a failure to begin that transaction. It means SQLite refused to start the transaction, typically because the database handle is unusable or the connection cannot be obtained.","triggerScenarios":"db.db.BeginTx(ctx, nil) fails during the checkpoint boundary-snapshot phase: the *sql.DB is closed, the context is already canceled/timed out, or the driver cannot open a connection (too many open connections, connection pool exhausted).","commonSituations":"Context deadline exceeded because the checkpoint took too long; db.Close() called concurrently by application code; connection pool limits (MaxOpenConns) exhausted by other application queries.","solutions":["Check the wrapped error: 'context canceled/deadline exceeded' means the checkpoint ctx timed out — increase timeouts or reduce checkpoint frequency.","Ensure the application does not close the *sql.DB while Litestream replication is running.","Raise connection pool limits (db.SetMaxOpenConns) if other queries are starving the pool.","Retry the sync; transient begin failures resolve on the next cycle."],"exampleFix":"// before\nctx, cancel := context.WithTimeout(ctx, 2*time.Second)\n// after\nctx, cancel := context.WithTimeout(ctx, 30*time.Second) // allow checkpoint + snapshot to finish","handlingStrategy":"try-catch","validationCode":"select {\ncase <-ctx.Done():\n    return ctx.Err() // don't start a checkpoint with an already-cancelled context\ndefault:\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"begin:\") {\n    if errors.Is(err, context.DeadlineExceeded) {\n        // lengthen timeout and retry\n    }\n}","preventionTips":["Give checkpoint/sync contexts generous timeouts relative to WAL size.","Avoid calling db.Close() concurrently with replication.","Size the connection pool so Litestream can always get a connection.","Check for 'database is closed' wrapped errors indicating lifecycle misuse."],"tags":["sqlite","transaction","checkpoint","context-timeout"],"backgroundTag":"database-query-failed","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}