go-task/task · error

context cancelled while waiting for repository lock: %w

Error message

context cancelled while waiting for repository lock: %w

What it means

Before cloning a remote git Taskfile, getOrCloneRepo checks ctx.Err(). If the context is already cancelled/deadlined while (about to be) waiting to acquire/clone the repository, the context error is wrapped with this message.

Source

Thrown at taskfile/node_git.go:141

// The cache directory is /tmp/task-git-repos/{cache_key}/
func (node *GitNode) getOrCloneRepo(ctx context.Context) (string, error) {
	cacheKey := node.repoCacheKey()

	repoMutex := globalGitRepoCache.getLockForRepo(cacheKey)
	repoMutex.Lock()
	defer repoMutex.Unlock()

	cacheDir := filepath.Join(os.TempDir(), "task-git-repos", cacheKey)

	// Check cache FIRST - if already cloned, no network needed, timeout irrelevant
	gitDir := filepath.Join(cacheDir, ".git")
	if _, err := os.Stat(gitDir); err == nil {
		return cacheDir, nil
	}

	// 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
}

View on GitHub (pinned to 385e5ad92a)

Solutions

  1. Re-run the command; this is usually a cancellation, not a data problem
  2. Increase any deadline/timeout applied to the context wrapping Task
  3. Pre-cache the repo by fetching the include manually or warming the cache dir
  4. Check network/proxy speed if timeouts fire routinely before cloning completes

Example fix

// before
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
// after
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
Defensive patterns

Strategy: retry

Validate before calling

select {
case <-ctx.Done():
    return ctx.Err() // caller already knows context is dead; resolve before invoking task
default:
}
if _, err := net.LookupHost(gitHost); err != nil {
    return fmt.Errorf("git host unreachable: %w", err)
}

Type guard

func contextAlive(ctx context.Context) bool {
    return ctx.Err() == nil
}

Try / catch

data, err := node.ReadContext(ctx)
if err != nil {
    if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
        // retry with a fresh, longer-lived context
    }
    return err
}

Prevention

When it happens

Trigger: ReadContext -> getOrCloneRepo with a ctx that is cancelled or has passed its deadline before the clone begins — e.g. `task` invocation with a timeout that expired, or Ctrl-C while resolving a remote `https://...git` include.

Common situations: Slow network plus a short context deadline; user interrupt during remote Taskfile resolution; orchestrators (CI job timeouts) cancelling the parent context before the clone starts.

Related errors


AI-assisted analysis of go-task/task@385e5ad92a (2026-09-05). Data as JSON: /api/errors/528cede9fd1fbe78. Report an issue: GitHub.