{"record":{"id":"427a281047c703b7","repo":"gastownhall/beads","slug":"reading-current-database-w","errorCode":null,"errorMessage":"reading current database: %w","messagePattern":"reading current database: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/schema/converged.go","lineNumber":129,"sourceCode":"// A database that does not exist yet is a fresh bootstrap: report false so the\n// caller falls through to the locked path, whose CREATE DATABASE arbitrates\n// creation and issues the #5012 fresh-bootstrap heal capability.\n//\n// Selecting is also what makes skipping a caller's locked bootstrap\n// preparation safe: preparation creates the database and USEs it, and both\n// have provably happened here — the database existed before we touched it (so\n// preparation's bare CREATE DATABASE could only have failed with \"database\n// exists\" and captured no heal authority), and the selector issues the same\n// USE preparation would.\n//\n// The existence probe is not decoration. A Dolt session that issues a FAILING\n// statement stays pinned to its pre-statement catalog snapshot, so a USE of a\n// not-yet-created database would poison this pooled connection for the rest of\n// its life (be-bv7x). Probe with a query that always succeeds, then act.\nfunc selectTargetDatabase(ctx context.Context, db DBConn, databaseName string, selector DatabaseSelector) (bool, string, error) {\n\tvar current sql.NullString\n\tif err := db.QueryRowContext(ctx, \"SELECT DATABASE()\").Scan(&current); err != nil {\n\t\treturn false, \"\", fmt.Errorf(\"reading current database: %w\", err)\n\t}\n\tif current.Valid && current.String == databaseName {\n\t\treturn true, \"\", nil\n\t}\n\tif selector == nil {\n\t\treturn false, \"\", nil\n\t}\n\n\tvar exists int\n\tif err := db.QueryRowContext(ctx,\n\t\t\"SELECT COUNT(*) FROM information_schema.schemata WHERE schema_name = ?\",\n\t\tdatabaseName,\n\t).Scan(&exists); err != nil {\n\t\treturn false, \"\", fmt.Errorf(\"probing database %q existence: %w\", databaseName, err)\n\t}\n\tif exists == 0 {\n\t\treturn false, \"\", nil\n\t}","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/schema/converged.go#L111-L147","documentation":"This error wraps a failure to run `SELECT DATABASE()` while determining whether the pooled session is already pinned to the target database (selectTargetDatabase). The check exists because a USE of a not-yet-created database would poison the pooled connection (be-bv7x), so the code probes first; if even the probe fails, the connection or context is unhealthy. Callers (alreadyConverged via MigrateUpWithLock) cannot take the fast path.","triggerScenarios":"SELECT DATABASE() returns a driver error: connection closed or dropped, context cancelled or deadline exceeded, server unavailable, or the pooled connection was killed server-side.","commonSituations":"Dolt server restart between pool creation and first query; idle connection reaped by the server (wait_timeout); context timeout too tight during startup; network partition to a remote Dolt server.","solutions":["Retry the open or migration — a fresh connection from the pool usually succeeds.","Enable connection health checks or ping before use; keep pool idle lifetime below server wait_timeout.","Increase context timeouts if deadlines are hit during startup.","Check Dolt server logs and connectivity (host, port, TLS) if failures repeat."],"exampleFix":"// before: probe failure aborts\nif err := db.QueryRowContext(ctx, \"SELECT DATABASE()\").Scan(&current); err != nil {\n\treturn false, \"\", fmt.Errorf(\"reading current database: %w\", err)\n}\n// after: retry once for transient pool-connection errors\nif err := db.QueryRowContext(ctx, \"SELECT DATABASE()\").Scan(&current); err != nil {\n\tif !isRetryableConnErr(err) {\n\t\treturn false, \"\", fmt.Errorf(\"reading current database: %w\", err)\n\t}\n\tif retryErr := db.QueryRowContext(ctx, \"SELECT DATABASE()\").Scan(&current); retryErr != nil {\n\t\treturn false, \"\", fmt.Errorf(\"reading current database: %w\", retryErr)\n\t}\n}","handlingStrategy":"retry","validationCode":"// Ping the connection before schema probes to evict dead pooled connections\nif err := db.PingContext(ctx); err != nil {\n\treturn fmt.Errorf(\"database connection unhealthy: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"res, err := openDatabase(ctx)\nif err != nil && strings.Contains(err.Error(), \"reading current database:\") {\n\tif isTransient(err) { // net.OpError, context deadline, server gone\n\t\tres, err = openDatabase(ctx) // fresh pool connection\n\t}\n}","preventionTips":["Set connection MaxIdleTime below the server's wait_timeout so stale connections are reaped","Ping or health-check pooled connections before first use","Use adequately generous context timeouts during startup","Monitor Dolt server availability and restarts"],"tags":["database","connection","dolt"],"backgroundTag":"database-probe-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}