{"record":{"id":"70c31d97300814f4","repo":"benbjohnson/litestream","slug":"litestream-lock-w","errorCode":null,"errorMessage":"_litestream_lock: %w","messagePattern":"_litestream_lock: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"db.go","lineNumber":2504,"sourceCode":"\tif err != nil {\n\t\treturn false, fmt.Errorf(\"cannot copy wal before checkpoint: %w\", err)\n\t}\n\texec.applySyncResult(result)\n\n\tvar barrierTx *sql.Tx\n\tif mode == CheckpointModePassive {\n\t\tbarrierTx, err = db.db.BeginTx(ctx, nil)\n\t\tif err != nil {\n\t\t\treturn false, fmt.Errorf(\"begin passive checkpoint barrier: %w\", err)\n\t\t}\n\t\tdefer func() {\n\t\t\tif barrierTx != nil {\n\t\t\t\t_ = rollback(barrierTx)\n\t\t\t}\n\t\t}()\n\n\t\tif _, err := barrierTx.ExecContext(ctx, `INSERT INTO _litestream_lock (id) VALUES (1);`); err != nil {\n\t\t\treturn false, fmt.Errorf(\"_litestream_lock: %w\", err)\n\t\t}\n\n\t\tresult, err = db.verifyAndSyncWithExecutor(ctx, true, exec, 0)\n\t\tif err != nil {\n\t\t\treturn false, fmt.Errorf(\"cannot seal wal before passive checkpoint: %w\", err)\n\t\t}\n\t\texec.applySyncResult(result)\n\t}\n\n\tframeSize := int64(db.pageSize + WALFrameHeaderSize)\n\tpreCheckpointFrameN := 0\n\tif exec.state.lastSyncedWALOffset > WALHeaderSize {\n\t\tpreCheckpointFrameN = int((exec.state.lastSyncedWALOffset - WALHeaderSize) / frameSize)\n\t}\n\n\t// Execute checkpoint and immediately issue a write to the WAL to ensure\n\t// a new page is written.\n\tdb.setSyncDiagPhase(diagPhaseCheckpointExec,","sourceCodeStart":2486,"sourceCodeEnd":2522,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/db.go#L2486-L2522","documentation":"Inside the passive-checkpoint barrier transaction, Litestream inserts into its internal _litestream_lock table to serialize against other sync activity. This error wraps the failure of that INSERT, aborting the passive checkpoint.","triggerScenarios":"In checkpointWithExecutor (passive mode) when barrierTx.ExecContext(ctx, `INSERT INTO _litestream_lock (id) VALUES (1);`) fails — table missing (fresh/restored DB before Litestream initialized its schema), database locked, or disk I/O error.","commonSituations":"The _litestream_lock table was dropped or the DB was replaced/restored without Litestream re-initializing, a foreign process holds a write lock, or the filesystem is read-only/full.","solutions":["Restart Litestream so it re-creates its internal schema on the database","Verify the table exists: `sqlite3 app.db '.tables' | grep _litestream_lock`","Check for competing write locks or a read-only filesystem/mount","Check disk space and database file permissions"],"exampleFix":"// before\nsqlite3 app.db 'DROP TABLE _litestream_lock;'   # someone cleaned up tables\n// after\nsystemctl restart litestream   # recreates internal tables\nsqlite3 app.db '.tables' | grep _litestream_lock","handlingStrategy":"try-catch","validationCode":"// confirm litestream's internal schema exists\nrows, _ := db.Query(\"SELECT count(*) FROM sqlite_master WHERE name='_litestream_lock'\")\n// count==0 => litestream has not initialized this database","typeGuard":null,"tryCatchPattern":"// go\nif err := checkpoint(ctx, CheckpointModePassive); err != nil {\n    if strings.Contains(err.Error(), \"_litestream_lock\") {\n        // schema missing or locked: restart litestream to re-init; check read-only fs\n    }\n}","preventionTips":["Never drop litestream's internal tables","Restart litestream after restoring/replacing a database file","Ensure the DB mount is writable and has free space","Don't run other tools that take exclusive locks during checkpoints"],"tags":["sqlite","checkpoint","lock-table","sql"],"backgroundTag":"database-write-failed","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}