{"record":{"id":"e588bd7dce63f974","repo":"benbjohnson/litestream","slug":"populate-table-s-w","errorCode":null,"errorMessage":"populate table %s: %w","messagePattern":"populate table (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/litestream-test/populate.go","lineNumber":143,"sourceCode":"\n\ttotalRows := int(targetBytes / int64(c.RowSize))\n\trowsPerTable := totalRows / c.TableCount\n\tif rowsPerTable == 0 {\n\t\trowsPerTable = 1\n\t}\n\n\tslog.Info(\"Populating database\",\n\t\t\"target_bytes\", targetBytes,\n\t\t\"total_rows\", totalRows,\n\t\t\"rows_per_table\", rowsPerTable,\n\t)\n\n\tstartTime := time.Now()\n\tfor tableIdx := 0; tableIdx < c.TableCount; tableIdx++ {\n\t\ttableName := fmt.Sprintf(\"test_table_%d\", tableIdx)\n\n\t\tif err := c.populateTable(ctx, db, tableName, rowsPerTable); err != nil {\n\t\t\treturn fmt.Errorf(\"populate table %s: %w\", tableName, err)\n\t\t}\n\n\t\tcurrentSize, _ := getDatabaseSize(c.DB)\n\t\tprogress := float64(currentSize) / float64(targetBytes) * 100\n\t\tslog.Info(\"Progress\",\n\t\t\t\"table\", tableName,\n\t\t\t\"current_size_mb\", currentSize/1024/1024,\n\t\t\t\"progress_percent\", fmt.Sprintf(\"%.1f\", progress),\n\t\t)\n\n\t\tif currentSize >= targetBytes {\n\t\t\tbreak\n\t\t}\n\t}\n\n\tduration := time.Since(startTime)\n\tfinalSize, _ := getDatabaseSize(c.DB)\n","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/cmd/litestream-test/populate.go#L125-L161","documentation":"populateDatabase wraps a failure from populateTable for a given test table in this error. After creating tables, each table is filled with rowsPerTable rows in batches; any failure inside populateTable (transaction begin, prepare, insert, commit) is surfaced here with the table name. The remaining tables are not populated and the command exits.","triggerScenarios":"populateTable returns an error for table test_table_%d: the batch insert transaction fails to begin, the INSERT statement fails to prepare or execute, or the commit fails. The original cause is available via errors.Unwrap.","commonSituations":"Disk filling mid-population on a large target size; context cancellation surfacing through a failing database call; locked database from a concurrent reader (e.g. litestream or a monitoring query).","solutions":["Inspect the wrapped cause (the insert/commit/begin error) to find the root failure.","Check free disk space; SQLite writes fail with SQLITE_FULL when out of space.","Reduce target size or RowSize to fit available disk.","Ensure no competing process holds a write lock during population."],"exampleFix":"// before\nerr := c.populateTable(ctx, db, tableName, rowsPerTable) // opaque failure\n// after\nerr := c.populateTable(ctx, db, tableName, rowsPerTable)\nif err != nil {\n    slog.Error(\"populate failed\", \"table\", tableName, \"cause\", errors.Unwrap(err))\n}","handlingStrategy":"retry","validationCode":"// preflight: disk space and lock check before population\nif fi, err := os.Stat(filepath.Dir(c.DB)); err != nil {\n    return fmt.Errorf(\"db dir unavailable: %w\", err)\n}\n// verify no other writer holds the db\nif conn, err := os.OpenFile(c.DB, os.O_RDWR, 0); err != nil {\n    return fmt.Errorf(\"db not writable: %w\", err)\n} else {\n    conn.Close()\n}","typeGuard":null,"tryCatchPattern":"if err := c.populateTable(ctx, db, tableName, rowsPerTable); err != nil {\n    if errors.Is(err, sqlite.ErrBusy) || strings.Contains(err.Error(), \"SQLITE_BUSY\") {\n        time.Sleep(time.Second)\n        return c.populateTable(ctx, db, tableName, rowsPerTable) // retry once\n    }\n    return fmt.Errorf(\"populate table %s: %w\", tableName, err)\n}","preventionTips":["Estimate final size (target-bytes + WAL overhead) against free disk before starting.","Run populate exclusively; stop litestream/monitoring readers that take locks.","Unwrap the error to log the root cause per table.","Handle context cancellation before starting a new table loop iteration."],"tags":["sqlite","bulk-insert","database"],"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-14T00:17:10.932Z"}