{"record":{"id":"fc07f7d68f57ad2b","repo":"benbjohnson/litestream","slug":"open-database-w-fc07f7","errorCode":null,"errorMessage":"open database: %w","messagePattern":"open database: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/litestream-test/populate.go","lineNumber":76,"sourceCode":"\t\t\"page_size\", c.PageSize,\n\t)\n\n\tif err := c.populateDatabase(ctx, targetBytes); err != nil {\n\t\treturn fmt.Errorf(\"populate database: %w\", err)\n\t}\n\n\tslog.Info(\"Database population complete\", \"db\", c.DB)\n\treturn nil\n}\n\nfunc (c *PopulateCommand) populateDatabase(ctx context.Context, targetBytes int64) error {\n\tif err := os.Remove(c.DB); err != nil && !os.IsNotExist(err) {\n\t\tslog.Warn(\"Could not remove existing database\", \"error\", err)\n\t}\n\n\tdb, err := sql.Open(\"sqlite3\", c.DB)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"open database: %w\", err)\n\t}\n\tdefer db.Close()\n\n\tif _, err := db.Exec(fmt.Sprintf(\"PRAGMA page_size = %d\", c.PageSize)); err != nil {\n\t\treturn fmt.Errorf(\"set page size: %w\", err)\n\t}\n\n\tif _, err := db.Exec(\"PRAGMA journal_mode = WAL\"); err != nil {\n\t\treturn fmt.Errorf(\"set journal mode: %w\", err)\n\t}\n\n\tif _, err := db.Exec(\"PRAGMA synchronous = NORMAL\"); err != nil {\n\t\treturn fmt.Errorf(\"set synchronous: %w\", err)\n\t}\n\n\tfor i := 0; i < c.TableCount; i++ {\n\t\ttableName := fmt.Sprintf(\"test_table_%d\", i)\n","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/cmd/litestream-test/populate.go#L58-L94","documentation":"populateDatabase calls os.Remove on any existing database, then opens the (new) file with `sql.Open(\"sqlite3\", c.DB)` and wraps failures as \"open database\". Since database/sql's Open is lazy, this error generally means a bad DSN/path or an unavailable driver rather than a runtime connection problem; actual file-level failures typically appear at the first Exec (see \"set page size\").","triggerScenarios":"`litestream-test populate -db <path>` where the DSN is rejected by the driver, the sqlite3 driver is not registered in the build, or the driver fails immediately opening the path (unwritable directory, path is a directory, invalid characters in path).","commonSituations":"-db pointing at an existing directory instead of a file path; unwritable parent directory; building without the sqlite3 driver import; path characters that break the DSN.","solutions":["Ensure the -db value is a file path in a writable directory (not a directory itself) and check parent-directory write permissions.","Verify the sqlite3 driver is registered in the build (correct import/CGO setup) and rebuild if needed.","If the real failure appears only on the first Exec, look at the subsequent wrapped errors (\"set page size\", \"set journal mode\") for the file-level root cause."],"exampleFix":"// before\ndb, err := sql.Open(\"sqlite3\", c.DB)\nif err != nil {\n    return fmt.Errorf(\"open database: %w\", err)\n}\n// after — detect file-level open failures eagerly\ndb, err := sql.Open(\"sqlite3\", c.DB)\nif err != nil {\n    return fmt.Errorf(\"open database: %w\", err)\n}\nif err := db.Ping(); err != nil {\n    return fmt.Errorf(\"open database: %w\", err)\n}","handlingStrategy":"validation","validationCode":"import { statSync } from \"fs\";\nif (existsSync(dbPath) && statSync(dbPath).isDirectory()) {\n  throw new Error(`-db must be a file path, not a directory: ${dbPath}`);\n}\nif (!statSync(path.dirname(dbPath)).isDirectory()) throw new Error(\"parent directory missing: \" + path.dirname(dbPath));","typeGuard":"function isWritableFilePath(p) {\n  try { return !existsSync(p) || statSync(p).isFile(); } catch { return false; }\n}","tryCatchPattern":"try {\n  await run(\"litestream-test\", [\"populate\", \"-db\", dbPath]);\n} catch (e) {\n  if (String(e).includes(\"open database\")) {\n    console.error(`Could not open ${dbPath}; check it is a file path in a writable directory and the sqlite3 driver is built in.`);\n  }\n  throw e;\n}","preventionTips":["Pass a file path (not a directory) to -db and ensure the parent directory is writable.","Ensure the binary is built with the sqlite3 driver registered.","Avoid odd characters in paths that could corrupt the DSN."],"tags":["sqlite","database","cli"],"backgroundTag":"file-open-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"}