{"record":{"id":"2844ddf39023ab65","repo":"benbjohnson/litestream","slug":"minimum-checkpoint-page-count-required","errorCode":null,"errorMessage":"minimum checkpoint page count required","messagePattern":"minimum checkpoint page count required","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"db.go","lineNumber":788,"sourceCode":"func (db *DB) Open() (err error) {\n\tdb.mu.Lock()\n\tif db.opened {\n\t\tdb.mu.Unlock()\n\t\treturn nil // already open\n\t}\n\t// Recreate context for fresh start (handles reopen after close)\n\tdb.ctx, db.cancel = context.WithCancel(context.Background())\n\tdb.mu.Unlock()\n\n\t// Validate fields on database.\n\tif db.Replica == nil {\n\t\treturn fmt.Errorf(\"replica required before opening database\")\n\t}\n\tif db.Replica.Client == nil {\n\t\treturn fmt.Errorf(\"replica client required before opening database\")\n\t}\n\tif db.MinCheckpointPageN <= 0 {\n\t\treturn fmt.Errorf(\"minimum checkpoint page count required\")\n\t}\n\n\t// Clear old temporary files that my have been left from a crash.\n\tif err := removeTmpFiles(db.metaPath); err != nil {\n\t\treturn fmt.Errorf(\"cannot remove tmp files: %w\", err)\n\t}\n\n\t// Set the compactor client once before starting any goroutines.\n\tdb.compactor.VerifyCompaction = db.VerifyCompaction\n\tdb.compactor.RetentionEnabled = db.RetentionEnabled\n\tdb.compactor.client = db.Replica.Client\n\n\t// Start monitoring SQLite database in a separate goroutine.\n\tif db.MonitorInterval > 0 {\n\t\tdb.wg.Add(1)\n\t\tgo func() { defer db.wg.Done(); db.monitor() }()\n\t}\n","sourceCodeStart":770,"sourceCodeEnd":806,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/db.go#L770-L806","documentation":"DB.Open requires db.MinCheckpointPageN to be strictly positive. This value is the WAL page-count threshold that triggers passive checkpoints, and a zero or negative value would make the checkpoint loop never fire (or behave nonsensically). It is part of the same open-time field validation block.","triggerScenarios":"Instantiating a DB via the library API and leaving MinCheckpointPageN at its zero value; explicitly setting it to 0 or a negative number in custom construction code.","commonSituations":"Programmatic users of litestream as a library who build DB structs by hand (the CLI default config path sets this automatically); copy-pasted struct literal initialization omitting the field.","solutions":["Set db.MinCheckpointPageN = litestream.DefaultMinCheckpointPageN (the library's default, typically 1000).","Choose a sensible positive page count appropriate for your write volume before Open().","Prefer constructing databases through the config loader, which fills in defaults."],"exampleFix":"// before\ndb := litestream.NewDB(\"/data/app.db\")\nif err := db.Open(); err != nil { ... }\n// after\ndb := litestream.NewDB(\"/data/app.db\")\ndb.MinCheckpointPageN = litestream.DefaultMinCheckpointPageN\nif err := db.Open(); err != nil { ... }","handlingStrategy":"validation","validationCode":"if db.MinCheckpointPageN <= 0 {\n    db.MinCheckpointPageN = litestream.DefaultMinCheckpointPageN\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never hand-build DB structs without defaults; use NewDB plus explicit defaults.","Review struct literals for omitted zero-value fields."],"tags":["database","configuration","validation"],"backgroundTag":"invalid-config-value","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"}