{"record":{"id":"0d5245a7eaca7ec3","repo":"gastownhall/beads","slug":"create-branch-s-w","errorCode":null,"errorMessage":"create branch %s: %w","messagePattern":"create branch (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/versioncontrolops/branches.go","lineNumber":39,"sourceCode":"\t\t}\n\t\tbranches = append(branches, name)\n\t}\n\treturn branches, rows.Err()\n}\n\n// CurrentBranch returns the name of the active branch.\nfunc CurrentBranch(ctx context.Context, db DBConn) (string, error) {\n\tvar branch string\n\tif err := db.QueryRowContext(ctx, \"SELECT active_branch()\").Scan(&branch); err != nil {\n\t\treturn \"\", fmt.Errorf(\"get current branch: %w\", err)\n\t}\n\treturn branch, nil\n}\n\n// CreateBranch creates a new Dolt branch from the current HEAD.\nfunc CreateBranch(ctx context.Context, db DBConn, name string) error {\n\tif _, err := db.ExecContext(ctx, \"CALL DOLT_BRANCH(?)\", name); err != nil {\n\t\treturn fmt.Errorf(\"create branch %s: %w\", name, err)\n\t}\n\treturn nil\n}\n\n// DeleteBranch force-deletes a Dolt branch.\nfunc DeleteBranch(ctx context.Context, db DBConn, name string) error {\n\tif _, err := db.ExecContext(ctx, \"CALL DOLT_BRANCH('-D', ?)\", name); err != nil {\n\t\treturn fmt.Errorf(\"delete branch %s: %w\", name, err)\n\t}\n\treturn nil\n}\n\n// CheckoutBranch switches the active session to the named branch.\nfunc CheckoutBranch(ctx context.Context, db DBConn, name string) error {\n\tif _, err := db.ExecContext(ctx, \"CALL DOLT_CHECKOUT(?)\", name); err != nil {\n\t\treturn fmt.Errorf(\"checkout branch %s: %w\", name, err)\n\t}\n\treturn nil","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/versioncontrolops/branches.go#L21-L57","documentation":"CreateBranch runs CALL DOLT_BRANCH(?) to create a branch from the current HEAD and wraps failures as 'create branch <name>: %w'. Dolt rejects the call when the branch name already exists, is invalid, or when the connection/session is unhealthy. The name is included so the failing branch is identifiable.","triggerScenarios":"Calling CreateBranch with a name that already exists (DOLT_BRANCH without -c/force fails on duplicates), an illegal branch name, or when the Dolt call errors from a connection issue.","commonSituations":"Re-running an init/branch bootstrap on an already-initialized repo; branch names with spaces or invalid characters; concurrent workers racing to create the same branch; stale connections after server restart.","solutions":["Check existence first (CurrentBranch + querying dolt_branches) and skip creation if the branch already exists","Sanitize/validate the branch name (no spaces, valid ref characters) before calling","Handle the duplicate-branch case as a no-op success by inspecting the wrapped driver error"],"exampleFix":"// before\nerr := versioncontrolops.CreateBranch(ctx, db, name)\n// after\nexists, _ := branchExists(ctx, db, name)\nif !exists {\n    err := versioncontrolops.CreateBranch(ctx, db, name)\n}","handlingStrategy":"try-catch","validationCode":"var count int\n_ = db.QueryRowContext(ctx,\n    \"SELECT COUNT(*) FROM dolt_branches WHERE name = ?\", name).Scan(&count)\n// count > 0 means branch already exists; skip CreateBranch","typeGuard":null,"tryCatchPattern":"err := versioncontrolops.CreateBranch(ctx, db, name)\nif err != nil {\n    if strings.Contains(err.Error(), \"already exists\") || strings.Contains(err.Error(), \"duplicate\") {\n        return nil // treat as success\n    }\n    return fmt.Errorf(\"create branch %s: %w\", name, err)\n}","preventionTips":["Check dolt_branches before creating","Validate branch names (ref-safe characters, no spaces)","Serialize branch creation across concurrent workers","Re-verify connection health before DDL-like procedure calls"],"tags":["dolt","sql","branch","database"],"backgroundTag":"dolt-branch-operation-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}