go-task/task · error
failed to clone repository
Error message
failed to clone repository: %w
What it means
getOrCloneRepo clones a remote git Taskfile via getter.Client.Get(). On any clone failure (auth, network, bad URL, missing repo), the cache directory is removed and the getter error is wrapped with this message.
Solutions
- Verify the include URL is correct and the repo/branch exists (git clone <url> manually)
- Set up credentials: SSH keys for git@ URLs or a token for private HTTPS repos
- Check network/proxy/VPN connectivity to the git host
- Inspect the wrapped cause for the underlying git/getter error; retry after fixing
Example fix
# before (includes in Taskfile) includes: - ops: https://git.example.com/team/ops-taskfile.git@main # after (corrected URL / existing ref) includes: - ops: https://git.example.com/team/taskfiles.git@main
Defensive patterns
Strategy: retry
Validate before calling
u, err := url.Parse(includeURL)
if err != nil {
return err
}
conn, err := net.DialTimeout("tcp", net.JoinHostPort(u.Host, "443"), 5*time.Second)
if err != nil {
return fmt.Errorf("cannot reach git host %s: %w", u.Host, err)
}
conn.Close() Type guard
func isReachableGitURL(raw string) bool {
u, err := url.Parse(raw)
if err != nil || u.Host == "" {
return false
}
c, err := net.DialTimeout("tcp", u.Host+":443", 3*time.Second)
if err != nil {
return false
}
c.Close()
return true
} Try / catch
data, err := node.ReadContext(ctx)
if err != nil {
if strings.Contains(err.Error(), "failed to clone repository") {
// check credentials/network, maybe retry with backoff
}
return err
} Prevention
- Verify include URLs and refs exist before committing them
- Configure SSH keys or credential helpers for private repos
- Warm the git node cache before offline/CI runs
- Test the URL with a manual `git clone` first
When it happens
Trigger: ReadContext -> getOrCloneRepo: client.Get() returns an error while cloning the repository into cacheDir — unreachable host, private repo without credentials, nonexistent ref/repo, or TLS problems.
Common situations: Cloning a private Taskfile repo without SSH keys or tokens; typo in the include URL; corporate proxy/firewall blocking git over HTTPS; referencing a branch or tag that does not exist.
Related errors
AI-assisted analysis of go-task/task@385e5ad92a (2026-09-05).
Data as JSON: /api/errors/ba14d92464914388.
Report an issue: GitHub.
Appendix: source
Thrown at taskfile/node_git.go:155
}
// Only check context if we need to clone (requires network)
if err := ctx.Err(); err != nil {
return "", fmt.Errorf("context cancelled while waiting for repository lock: %w", err)
}
getterURL := node.buildURL()
client := &getter.Client{
Ctx: ctx,
Src: getterURL,
Dst: cacheDir,
Mode: getter.ClientModeDir,
}
if err := client.Get(); err != nil {
_ = os.RemoveAll(cacheDir)
return "", fmt.Errorf("failed to clone repository: %w", err)
}
return cacheDir, nil
}
func (node *GitNode) ReadContext(ctx context.Context) ([]byte, error) {
// Get or clone the repository into cache
repoDir, err := node.getOrCloneRepo(ctx)
if err != nil {
return nil, err
}
// Build path to Taskfile in the cached repo
// If node.path is empty, search in repo root; otherwise search in the specified path
// fsext.SearchPath handles both files and directories (searching for DefaultTaskfiles)
searchPath := repoDir
if node.path != "" {
searchPath = filepath.Join(repoDir, node.path)View on GitHub (pinned to 385e5ad92a)