argoproj/argo-workflows · error
failed to plain init: %w
Error message
failed to plain init: %w
What it means
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.
Source
Thrown at workflow/artifacts/git/git.go:138
Auth: auth,
Depth: depth,
SingleBranch: a.SingleBranch,
InsecureSkipTLS: g.InsecureSkipTLS,
}
if a.SingleBranch && a.Branch == "" {
return errors.New("single branch mode without a branch specified")
}
if a.SingleBranch {
cloneOptions.ReferenceName = plumbing.NewBranchReferenceName(a.Branch)
}
r, err := git.PlainClone(path, false, cloneOptions)
if errors.Is(err, transport.ErrEmptyRemoteRepository) {
logging.RequireLoggerFromContext(ctx).Info(ctx, "Cloned an empty repository")
var initErr error
r, initErr = git.PlainInit(path, false)
if initErr != nil {
return fmt.Errorf("failed to plain init: %w", initErr)
}
if _, remoteErr := r.CreateRemote(&config.RemoteConfig{Name: git.DefaultRemoteName, URLs: []string{a.Repo}}); remoteErr != nil {
return fmt.Errorf("failed to create remote %q: %w", a.Repo, remoteErr)
}
branchName := a.Revision
if branchName == "" {
branchName = "master"
}
if err = r.CreateBranch(&config.Branch{Name: branchName, Remote: git.DefaultRemoteName, Merge: plumbing.Master}); err != nil {
return fmt.Errorf("failed to create branch %q: %w", branchName, err)
}
return nil
} else if err != nil {
return fmt.Errorf("failed to clone %q: %w", a.Repo, err)
}
if len(a.Fetch) > 0 {
refSpecs := make([]config.RefSpec, len(a.Fetch))
for i, spec := range a.Fetch {View on GitHub (pinned to 35bff19146)
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.
Example fix
// before: retrying into a dirty path fails with 'repository already exists'
r, initErr = git.PlainInit(path, false)
// after: clear leftover state first
if _, statErr := os.Stat(filepath.Join(path, ".git")); statErr == nil {
os.RemoveAll(filepath.Join(path, ".git"))
}
r, initErr = git.PlainInit(path, false) Defensive patterns
Strategy: validation
Validate before calling
func ensureCleanTarget(path string) error {
if _, err := os.Stat(filepath.Join(path, ".git")); err == nil {
return fmt.Errorf("%s already contains a git repository; clean it before loading the artifact", path)
}
f, err := os.CreateTemp(path, ".write-test")
if err != nil {
return fmt.Errorf("artifact path %s is not writable: %w", path, err)
}
f.Close()
os.Remove(f.Name())
return nil
} Type guard
func isRepoExistsErr(err error) bool {
return errors.Is(err, git.ErrRepositoryAlreadyExists)
} Try / catch
err := artifactDriver.Load(ctx, artifact, path)
if err != nil && strings.Contains(err.Error(), "failed to plain init") {
if isRepoExistsErr(errors.Unwrap(err)) {
os.RemoveAll(filepath.Join(path, ".git"))
err = artifactDriver.Load(ctx, artifact, path)
}
}
if err != nil {
return fmt.Errorf("git artifact load failed: %w", err)
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- failed to create remote %q: %w
- failed to create branch %q: %w
- failed to test if %s is a directory: %w
- unable to open file %s: %w
- failed to clone %q: %w
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/60b3ac65c7ca2020.
Report an issue: GitHub.