{"record":{"id":"8f51cd6ae807cc58","repo":"gastownhall/beads","slug":"count-commits-w","errorCode":null,"errorMessage":"count commits: %w","messagePattern":"count commits: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/versioncontrolops/flatten.go","lineNumber":38,"sourceCode":"// pre-flatten chain, and GC alone reclaims nothing while they exist (bd-agctw).\n//\n// conn must be a single database connection (not a pooled *sql.DB) since the\n// stored procedures rely on session-scoped state (current branch, working set).\nfunc Flatten(ctx context.Context, conn DBConn) error {\n\t// Find the initial commit hash (oldest ancestor).\n\tvar initialHash string\n\tif err := conn.QueryRowContext(ctx,\n\t\t\"SELECT commit_hash FROM dolt_log ORDER BY date ASC LIMIT 1\",\n\t).Scan(&initialHash); err != nil {\n\t\treturn fmt.Errorf(\"find initial commit: %w\", err)\n\t}\n\n\t// Count commits to check if flatten is needed.\n\tvar commitCount int\n\tif err := conn.QueryRowContext(ctx,\n\t\t\"SELECT COUNT(*) FROM dolt_log\",\n\t).Scan(&commitCount); err != nil {\n\t\treturn fmt.Errorf(\"count commits: %w\", err)\n\t}\n\tif commitCount <= 1 {\n\t\treturn nil // already flat\n\t}\n\n\texecSQL := func(name, query string, args ...interface{}) error {\n\t\tif _, err := conn.ExecContext(ctx, query, args...); err != nil {\n\t\t\treturn fmt.Errorf(\"flatten step %q: %w\", name, err)\n\t\t}\n\t\treturn nil\n\t}\n\n\tsteps := []struct {\n\t\tname  string\n\t\tquery string\n\t\targs  []interface{}\n\t}{\n\t\t{\"create temp branch\", \"CALL DOLT_BRANCH('flatten-tmp')\", nil},","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/versioncontrolops/flatten.go#L20-L56","documentation":"Flatten counts commits in dolt_log to decide whether flattening is needed. If the SELECT COUNT(*) query or Scan fails — connection error, context cancellation, database unavailability — the error is wrapped as \"count commits: %w\" and Flatten aborts before making any changes.","triggerScenarios":"Calling Flatten(ctx, conn) when the Dolt connection is down or dropped between queries; context deadline exceeded; the database is not a valid Dolt database so dolt_log does not exist.","commonSituations":"Server restart between the initial-commit lookup and the count query; connecting to a non-Dolt schema; network timeout on a remote sql-server; using a pooled connection whose session died.","solutions":["Check the wrapped error and verify the connection is healthy (db.PingContext), then retry.","Confirm the target is a Dolt database exposing dolt_log.","Use a single dedicated connection for the whole Flatten call, as required by its doc.","Prefer FlattenDryRun for read-only checks so failures never risk partial flatten steps."],"exampleFix":"// before\nversioncontrolops.Flatten(ctx, pooledDB)\n// after\nif err := conn.PingContext(ctx); err != nil { return err }\nif _, _, err := versioncontrolops.FlattenDryRun(ctx, conn); err != nil {\n    return fmt.Errorf(\"dolt unreachable: %w\", err)\n}\nversioncontrolops.Flatten(ctx, conn)","handlingStrategy":"try-catch","validationCode":"if err := conn.PingContext(ctx); err != nil {\n    return fmt.Errorf(\"dolt connection unhealthy: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"err := versioncontrolops.Flatten(ctx, conn)\nif err != nil && strings.Contains(err.Error(), \"count commits\") {\n    if errors.Is(err, context.DeadlineExceeded) {\n        return fmt.Errorf(\"flatten aborted before changes; increase timeout and retry\")\n    }\n    return err\n}","preventionTips":["Verify connectivity with PingContext before starting Flatten.","Use a context timeout generous enough for stored-procedure sequences.","Use a single session-scoped connection for the entire Flatten call.","Prefer FlattenDryRun for pre-flight checks."],"tags":["dolt","sql","database","flatten"],"backgroundTag":"database-query-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}