{"record":{"id":"60b3ac65c7ca2020","repo":"argoproj/argo-workflows","slug":"failed-to-plain-init-w","errorCode":null,"errorMessage":"failed to plain init: %w","messagePattern":"failed to plain init: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"workflow/artifacts/git/git.go","lineNumber":138,"sourceCode":"\t\tAuth:            auth,\n\t\tDepth:           depth,\n\t\tSingleBranch:    a.SingleBranch,\n\t\tInsecureSkipTLS: g.InsecureSkipTLS,\n\t}\n\tif a.SingleBranch && a.Branch == \"\" {\n\t\treturn errors.New(\"single branch mode without a branch specified\")\n\t}\n\tif a.SingleBranch {\n\t\tcloneOptions.ReferenceName = plumbing.NewBranchReferenceName(a.Branch)\n\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 {","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/workflow/artifacts/git/git.go#L120-L156","documentation":"This error is produced by Argo Workflows' git artifact driver (workflow/artifacts/git/git.go:138) when it handles a remote repository that reported itself as empty. go-git's PlainClone returns transport.ErrEmptyRemoteRepository, so the driver falls back to git.PlainInit to create a fresh local repository at the artifact path. The wrap means the fallback PlainInit call itself failed (e.g. the directory already contains a git repo or is unwritable), so the artifact could not be set up at all.","triggerScenarios":"git.PlainInit(path, false) fails during the empty-repository fallback path of ArtifactDriver.Load — typically because the target path already contains an existing .git directory (PlainInit returns git.ErrRepositoryAlreadyExists), the path is not writable, or a previous partial clone left state behind.","commonSituations":"Cloning a git artifact pointing at a brand-new/empty repo (e.g. a fresh branch with zero commits); retrying a workflow step into a volume where a previous failed init left a .git directory; mounting the artifact path read-only; using the same path for two artifacts.","solutions":["Check the wrapped initErr: if it is git.ErrRepositoryAlreadyExists or 'repository already exists', delete the .git directory (or the whole artifact path) before retrying the step.","Verify the artifact path volume is writable by the workflow pod's user; fix the volume mount or securityContext if not.","If the repo is genuinely empty, that is unusual — push at least one commit (or an initial branch) to the source repo so PlainClone succeeds normally.","If a prior run crashed mid-clone, use a fresh/empty emptyDir or clean the persistent volume between retries."],"exampleFix":"// before: retrying into a dirty path fails with 'repository already exists'\nr, initErr = git.PlainInit(path, false)\n// after: clear leftover state first\nif _, statErr := os.Stat(filepath.Join(path, \".git\")); statErr == nil {\n    os.RemoveAll(filepath.Join(path, \".git\"))\n}\nr, initErr = git.PlainInit(path, false)","handlingStrategy":"validation","validationCode":"func ensureCleanTarget(path string) error {\n\tif _, err := os.Stat(filepath.Join(path, \".git\")); err == nil {\n\t\treturn fmt.Errorf(\"%s already contains a git repository; clean it before loading the artifact\", path)\n\t}\n\tf, err := os.CreateTemp(path, \".write-test\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"artifact path %s is not writable: %w\", path, err)\n\t}\n\tf.Close()\n\tos.Remove(f.Name())\n\treturn nil\n}","typeGuard":"func isRepoExistsErr(err error) bool {\n\treturn errors.Is(err, git.ErrRepositoryAlreadyExists)\n}","tryCatchPattern":"err := artifactDriver.Load(ctx, artifact, path)\nif err != nil && strings.Contains(err.Error(), \"failed to plain init\") {\n\tif isRepoExistsErr(errors.Unwrap(err)) {\n\t\tos.RemoveAll(filepath.Join(path, \".git\"))\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":["Give each git artifact its own dedicated empty directory path.","Never reuse a persistent volume path across workflow retries without cleaning it first.","Ensure the artifact volume is writable by the pod's run-as user.","Push an initial commit to new repos so the empty-repo fallback path is never taken."],"tags":["git","go-git","artifact","filesystem"],"backgroundTag":"git-repository-init-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"}