go-task/task · error

checking remote file: %w

Error message

checking remote file: %w

What it means

RemoteExists in taskfile/taskfile.go wraps context errors when performing the HTTP HEAD/GET used to check whether a remote taskfile exists. It is thrown when the request fails specifically because the caller-supplied context was cancelled or its deadline expired while the HTTP client was executing. Any other request failure becomes a TaskfileFetchFailedError instead.

Source

Thrown at taskfile/taskfile.go:52

)

// RemoteExists will check if a file at the given URL Exists. If it does, it
// will return its URL. If it does not, it will search the search for any files
// at the given URL with any of the default Taskfile files names. If any of
// these match a file, the first matching path will be returned. If no files are
// found, an error will be returned.
func RemoteExists(ctx context.Context, u url.URL, client *http.Client) (*url.URL, error) {
	// Create a new HEAD request for the given URL to check if the resource exists
	req, err := http.NewRequestWithContext(ctx, "HEAD", u.String(), nil)
	if err != nil {
		return nil, errors.TaskfileFetchFailedError{URI: u.Redacted()}
	}

	// Request the given URL
	resp, err := client.Do(req)
	if err != nil {
		if ctx.Err() != nil {
			return nil, fmt.Errorf("checking remote file: %w", ctx.Err())
		}
		return nil, errors.TaskfileFetchFailedError{URI: u.Redacted()}
	}
	defer resp.Body.Close()

	// If the request was successful and the content type is allowed, return the
	// URL The content type check is to avoid downloading files that are not
	// Taskfiles It means we can try other files instead of downloading
	// something that is definitely not a Taskfile
	contentType := resp.Header.Get("Content-Type")
	if resp.StatusCode == http.StatusOK && slices.ContainsFunc(allowedContentTypes, func(s string) bool {
		return strings.Contains(contentType, s)
	}) {
		return &u, nil
	}

	// If the request was not successful, append the default Taskfile names to
	// the URL and return the URL of the first successful request

View on GitHub (pinned to 385e5ad92a)

Solutions

  1. Increase the context deadline passed to ReadContext (e.g. context.WithTimeout(ctx, 30*time.Second)) or remove the deadline if latency is expected.
  2. Check network connectivity / DNS / proxy settings for the remote host, since a hanging connection often is what exhausts the deadline.
  3. Retry the fetch with a fresh non-cancelled context once the cancellation cause (signal, parent timeout) is resolved.
  4. If your code cancels intentionally, stop propagating the error and treat it as an intentional abort.

Example fix

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

Strategy: retry

Validate before calling

// before fetching, ensure the context has sane headroom
if deadline, ok := ctx.Deadline(); ok && time.Until(deadline) < 5*time.Second {
    return errors.New("context deadline too short for remote taskfile fetch")
}

Try / catch

tf, err := node.ReadContext(ctx)
var ce error
if err != nil && errors.As(err, &ce) && ctx.Err() != nil {
    if errors.Is(ctx.Err(), context.DeadlineExceeded) {
        ctx = extendDeadline(ctx)
        tf, err = node.ReadContext(ctx) // retry once
    } else {
        return err // caller cancelled intentionally
    }
}

Prevention

When it happens

Trigger: Reading a remote taskfile (ReadContext -> RemoteExists) with a context that is cancelled by the caller, or whose deadline/timeout elapses before the server responds, so client.Do returns an error while ctx.Err() != nil.

Common situations: Slow or unreachable remote host combined with a short context deadline (e.g. context.WithTimeout of a few seconds), user Ctrl-C aborting a long-running task that fetches remote taskfiles, or CI jobs with tight per-step timeouts.

Related errors


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