{"record":{"id":"7c0a71ee3566ec1c","repo":"gastownhall/beads","slug":"flatten-step-q-w","errorCode":null,"errorMessage":"flatten step %q: %w","messagePattern":"flatten step %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/versioncontrolops/flatten.go","lineNumber":46,"sourceCode":"\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},\n\t\t{\"checkout temp branch\", \"CALL DOLT_CHECKOUT('flatten-tmp')\", nil},\n\t\t{\"soft reset to initial\", \"CALL DOLT_RESET('--soft', ?)\", []interface{}{initialHash}},\n\t\t{\"commit flattened snapshot\", \"CALL DOLT_COMMIT('-Am', 'flatten: squash all history into single commit')\", nil},\n\t\t{\"checkout main\", \"CALL DOLT_CHECKOUT('main')\", nil},\n\t\t{\"reset main to flattened\", \"CALL DOLT_RESET('--hard', 'flatten-tmp')\", nil},\n\t\t{\"delete temp branch\", \"CALL DOLT_BRANCH('-D', 'flatten-tmp')\", nil},\n\t}\n","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/versioncontrolops/flatten.go#L28-L64","documentation":"Inside Flatten, each squashing step (create temp branch, checkout, soft reset, commit, checkout main, hard reset, delete branch) is executed via an ExecContext helper that wraps failures as \"flatten step \\\"<name>\\\": %w\". The step name identifies exactly which stored procedure failed.","triggerScenarios":"Any of the seven steps failing: DOLT_BRANCH when 'flatten-tmp' already exists from a previous crashed run; DOLT_CHECKOUT failing due to dirty working set; DOLT_RESET/DOLT_COMMIT failing on a pooled connection that lost session-scoped branch state; conflict or unknown ref passed to a step.","commonSituations":"A prior Flatten attempt crashed leaving 'flatten-tmp' behind; caller passed a pooled *sql.DB so CHECKOUT affects a different session's connection; uncommitted changes blocking checkout; interrupted run mid-sequence.","solutions":["Read the quoted step name in the error to identify which stored procedure failed and address its specific cause.","Delete the leftover 'flatten-tmp' branch (CALL DOLT_BRANCH('-D', 'flatten-tmp')) if a prior run crashed at branch creation.","Ensure the working set is clean (WorkingSetClean) so DOLT_CHECKOUT/DOLT_COMMIT succeed.","Use a single dedicated connection, not a pool — session-scoped state (current branch) must persist across steps.","After a successful flatten, run PruneRemoteRefs and DoltGC per the docs to reclaim space."],"exampleFix":"// before\nversioncontrolops.Flatten(ctx, sqlDB) // fails at \"checkout temp branch\"\n// after\nclean, err := versioncontrolops.WorkingSetClean(ctx, conn)\nif err != nil || !clean { return fmt.Errorf(\"commit or stash before flatten\") }\nconn.ExecContext(ctx, \"CALL DOLT_BRANCH('-D', 'flatten-tmp')\") // clear stale branch from crashed run\nversioncontrolops.Flatten(ctx, singleConn)","handlingStrategy":"try-catch","validationCode":"clean, err := versioncontrolops.WorkingSetClean(ctx, conn)\nif err != nil { return err }\nif !clean { return fmt.Errorf(\"commit changes before flatten\") }\n// remove leftovers from a previously crashed run\nconn.ExecContext(ctx, \"CALL DOLT_BRANCH('-D', 'flatten-tmp')\")","typeGuard":null,"tryCatchPattern":"err := versioncontrolops.Flatten(ctx, conn)\nif err != nil {\n    var stepName string\n    if _, scanErr := fmt.Sscanf(err.Error(), \"flatten step %q\", &stepName); scanErr == nil {\n        return fmt.Errorf(\"flatten failed at %q; database may be mid-sequence, inspect branches: %w\", stepName, err)\n    }\n    return err\n}","preventionTips":["Never interrupt Flatten midway; if it crashed, manually clean up the 'flatten-tmp' branch before retrying.","Ensure the working set is clean so CHECKOUT and COMMIT steps succeed.","Always use a single dedicated connection — pooled connections lose Dolt session branch state mid-sequence.","Run Flatten during maintenance windows; follow with PruneRemoteRefs and DoltGC."],"tags":["dolt","stored-procedure","flatten","history"],"backgroundTag":"flatten-step-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}