{"record":{"id":"f772fc413aede207","repo":"gastownhall/beads","slug":"failed-to-count-issues-w","errorCode":null,"errorMessage":"failed to count issues: %w","messagePattern":"failed to count issues: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/doctor/perf_dolt.go","lineNumber":158,"sourceCode":"\tdb.SetMaxOpenConns(5)\n\tdb.SetMaxIdleConns(2)\n\n\tctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)\n\tdefer cancel()\n\tif err := db.PingContext(ctx); err != nil {\n\t\treturn fmt.Errorf(\"failed to ping server: %w\", err)\n\t}\n\tmetrics.ConnectionTime = time.Since(start).Milliseconds()\n\n\t// Run all diagnostics\n\treturn runDoltDiagnosticQueries(ctx, db, metrics)\n}\n\n// runDoltDiagnosticQueries runs the diagnostic queries and populates metrics\nfunc runDoltDiagnosticQueries(ctx context.Context, db *sql.DB, metrics *DoltPerfMetrics) error {\n\t// Get issue counts\n\tif err := db.QueryRowContext(ctx, \"SELECT COUNT(*) FROM issues\").Scan(&metrics.TotalIssues); err != nil {\n\t\treturn fmt.Errorf(\"failed to count issues: %w\", err)\n\t}\n\n\tif err := db.QueryRowContext(ctx, \"SELECT COUNT(*) FROM issues WHERE status != 'closed'\").Scan(&metrics.OpenIssues); err != nil {\n\t\tmetrics.OpenIssues = -1 // Mark as unavailable\n\t}\n\n\tif err := db.QueryRowContext(ctx, \"SELECT COUNT(*) FROM issues WHERE status = 'closed'\").Scan(&metrics.ClosedIssues); err != nil {\n\t\tmetrics.ClosedIssues = -1\n\t}\n\n\tif err := db.QueryRowContext(ctx, \"SELECT COUNT(*) FROM dependencies\").Scan(&metrics.Dependencies); err != nil {\n\t\tmetrics.Dependencies = -1\n\t}\n\n\t// Try to get Dolt version\n\tif err := db.QueryRowContext(ctx, \"SELECT dolt_version()\").Scan(&metrics.DoltVersion); err != nil {\n\t\tmetrics.DoltVersion = \"unknown\"\n\t}","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/doctor/perf_dolt.go#L140-L176","documentation":"runDoltDiagnosticQueries runs 'SELECT COUNT(*) FROM issues' to populate TotalIssues; if that query fails the error is wrapped as 'failed to count issues'. Subsequent open-issue count failures are tolerated (-1), so this first query is the hard gate — usually schema or connectivity problems.","triggerScenarios":"QueryRowContext on the issues table errors: table missing (empty/uninitialized or wrong database), connection dropped mid-query, permission denied, or context deadline exceeded.","commonSituations":"Connecting to a Dolt database without the beads schema (fresh server, wrong dbname); server restarted between ping and query; schema version mismatch after upgrade.","solutions":["Verify the database name in the DSN matches the beads database and that the issues table exists (SHOW TABLES)","Run schema migration/upgrade so the beads schema matches this bd version","Check connectivity stability and permissions on the issues table"],"exampleFix":"// before\ndb.QueryRowContext(ctx, \"SELECT COUNT(*) FROM issues\") // table missing in wrong db\n// after\nif err := ensureBeadsSchema(db); err != nil { return err } // creates/migrates schema first","handlingStrategy":"validation","validationCode":"var one int\nif err := db.QueryRowContext(ctx, \"SELECT 1 FROM issues LIMIT 1\").Scan(&one); err != nil {\n    // schema missing — run migrations before counting\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"failed to count issues\") {\n    var mysqlErr *mysql.MySQLError\n    if errors.As(errors.Unwrap(err), &mysqlErr) && mysqlErr.Number == 1146 { /* table missing: migrate */ }\n}","preventionTips":["Confirm the DSN points at the beads database name","Run bd schema migrations on upgrade before doctor checks","Check connectivity stability between ping and queries"],"tags":["beads","dolt","sql","schema"],"backgroundTag":"sql-query-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}