{"record":{"id":"8807d41427c02019","repo":"argoproj/argo-workflows","slug":"failed-to-create-branch-q-w","errorCode":null,"errorMessage":"failed to create branch %q: %w","messagePattern":"failed to create branch %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"workflow/artifacts/git/git.go","lineNumber":148,"sourceCode":"\t}\n\n\tr, err := git.PlainClone(path, false, cloneOptions)\n\tif errors.Is(err, transport.ErrEmptyRemoteRepository) {\n\t\tlogging.RequireLoggerFromContext(ctx).Info(ctx, \"Cloned an empty repository\")\n\t\tvar initErr error\n\t\tr, initErr = git.PlainInit(path, false)\n\t\tif initErr != nil {\n\t\t\treturn fmt.Errorf(\"failed to plain init: %w\", initErr)\n\t\t}\n\t\tif _, remoteErr := r.CreateRemote(&config.RemoteConfig{Name: git.DefaultRemoteName, URLs: []string{a.Repo}}); remoteErr != nil {\n\t\t\treturn fmt.Errorf(\"failed to create remote %q: %w\", a.Repo, remoteErr)\n\t\t}\n\t\tbranchName := a.Revision\n\t\tif branchName == \"\" {\n\t\t\tbranchName = \"master\"\n\t\t}\n\t\tif err = r.CreateBranch(&config.Branch{Name: branchName, Remote: git.DefaultRemoteName, Merge: plumbing.Master}); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to create branch %q: %w\", branchName, err)\n\t\t}\n\t\treturn nil\n\t} else if err != nil {\n\t\treturn fmt.Errorf(\"failed to clone %q: %w\", a.Repo, err)\n\t}\n\tif len(a.Fetch) > 0 {\n\t\trefSpecs := make([]config.RefSpec, len(a.Fetch))\n\t\tfor i, spec := range a.Fetch {\n\t\t\trefSpecs[i] = config.RefSpec(spec)\n\t\t}\n\t\topts := &git.FetchOptions{Auth: auth, RefSpecs: refSpecs, Depth: depth, InsecureSkipTLS: g.InsecureSkipTLS}\n\t\tif validateErr := opts.Validate(); validateErr != nil {\n\t\t\treturn fmt.Errorf(\"failed to validate fetch %v: %w\", refSpecs, validateErr)\n\t\t}\n\t\tif err = r.Fetch(opts); isFetchErr(err) {\n\t\t\treturn fmt.Errorf(\"failed to fetch %v: %w\", refSpecs, err)\n\t\t}\n\t}","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/workflow/artifacts/git/git.go#L130-L166","documentation":"This error is raised at workflow/artifacts/git/git.go:148 in the empty-remote-repository fallback path. After PlainInit and CreateRemote, the driver creates a local branch named after the artifact's revision (defaulting to 'master') with r.CreateBranch, wired to track origin/master. The wrap means go-git's CreateBranch rejected the branch config — usually because a branch with that name already exists, the name is invalid, or the underlying reference write failed.","triggerScenarios":"r.CreateBranch(&config.Branch{Name: branchName, Remote: git.DefaultRemoteName, Merge: plumbing.Master}) fails when loading a git artifact from an empty repository — duplicate branch name (ErrBranchExists), invalid branch name characters in a.Revision (e.g. a commit SHA or tag containing '/'), or a ref write error.","commonSituations":"Setting git.revision to a commit SHA or tag on an empty-looking repo — SHAs/tags are not valid branch names here; rerunning into a path that already has the branch; a repo where the default branch is 'main' but the fallback hardcodes Merge: plumbing.Master, causing tracking mismatches on later fetches.","solutions":["Check the wrapped err: 'branch already exists' means leftover state — wipe the artifact path and retry the step.","If a.Revision is a commit SHA or tag, note that this code only handles the empty-repo case; prefer pointing at a non-empty repo or a branch name.","Ensure the revision string is a valid git branch name (no '..', no trailing '.lock', no invalid characters).","Be aware the fallback tracks Merge: plumbing.Master even for non-master branchName; if your empty repo will use 'main', expect follow-up fetch oddities and push an initial commit to avoid this path entirely."],"exampleFix":"// before\nif err = r.CreateBranch(&config.Branch{Name: branchName, Remote: git.DefaultRemoteName, Merge: plumbing.Master}); err != nil {\n// after: tolerate pre-existing branch from a previous attempt\nif err = r.CreateBranch(&config.Branch{Name: branchName, Remote: git.DefaultRemoteName, Merge: plumbing.Master}); err != nil && !errors.Is(err, git.ErrBranchExists) {\n    return fmt.Errorf(\"failed to create branch %q: %w\", branchName, err)\n}","handlingStrategy":"validation","validationCode":"func validBranchName(name string) error {\n\tif name == \"\" {\n\t\treturn nil // driver defaults to master\n\t}\n\tif strings.ContainsAny(name, \" ~^:?*[\\\\\\\\\") || strings.HasSuffix(name, \".lock\") || strings.Contains(name, \"..\") {\n\t\treturn fmt.Errorf(\"%q is not a valid git branch name\", name)\n\t}\n\treturn nil\n}\n// call before submitting: validBranchName(wfArtifact.Git.Revision)","typeGuard":"func isBranchExistsErr(err error) bool {\n\treturn errors.Is(err, git.ErrBranchExists)\n}","tryCatchPattern":"err := artifactDriver.Load(ctx, artifact, path)\nif err != nil && strings.Contains(err.Error(), \"failed to create branch\") {\n\tif isBranchExistsErr(errors.Unwrap(err)) {\n\t\tos.RemoveAll(path) // clear stale branch state and retry\n\t\terr = artifactDriver.Load(ctx, artifact, path)\n\t}\n}\nif err != nil {\n\treturn fmt.Errorf(\"git artifact load failed: %w\", err)\n}","preventionTips":["Set git.revision to a branch name when the repo may be empty; use commit SHAs/tags only for populated repos.","Validate revision strings are legal git branch names before submitting the workflow.","Avoid reusing artifact paths across retries; wipe the path on retry.","Remember the fallback hardcodes master as the merge ref — prefer repos with an initial commit to bypass it."],"tags":["git","go-git","branch","artifact"],"backgroundTag":"git-branch-create-failed","analyzedSha":"35bff19146f5a6ada77468c431f2624bd577e373","analyzedAt":"2026-09-03T19:34:35.908Z","contentChangedAt":"2026-09-03T19:34:35.908Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}