nektos/act · warning

copy cancelled

Error message

copy cancelled

What it means

Returned by the FileCollector's WalkFunc when the context passed to CollectFiles has been cancelled (ctx.Done() fires) mid-walk. It is a cooperative-cancellation error: the artifact/cache file copy loop checks the context before each visited file and aborts the traversal.

Source

Thrown at pkg/filecollector/file_collector.go:137

func (*DefaultFs) Open(path string) (io.ReadCloser, error) {
	return os.Open(path)
}

func (*DefaultFs) Readlink(path string) (string, error) {
	return os.Readlink(path)
}

//nolint:gocyclo
func (fc *FileCollector) CollectFiles(ctx context.Context, submodulePath []string) filepath.WalkFunc {
	i, _ := fc.Fs.OpenGitIndex(path.Join(fc.SrcPath, path.Join(submodulePath...)))
	return func(file string, fi os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if ctx != nil {
			select {
			case <-ctx.Done():
				return fmt.Errorf("copy cancelled")
			default:
			}
		}

		sansPrefix := strings.TrimPrefix(file, fc.SrcPrefix)
		split := strings.Split(sansPrefix, string(filepath.Separator))
		// The root folders should be skipped, submodules only have the last path component set to "." by filepath.Walk
		if fi.IsDir() && len(split) > 0 && split[len(split)-1] == "." {
			return nil
		}
		var entry *index.Entry
		if i != nil {
			entry, err = i.Entry(strings.Join(split[len(submodulePath):], "/"))
		} else {
			err = index.ErrEntryNotFound
		}
		if err != nil && fc.Ignorer != nil && fc.Ignorer.Match(split, fi.IsDir()) {
			if fi.IsDir() {

View on GitHub (pinned to 4f41128141)

Solutions

  1. If the cancellation was accidental (aggressive timeout), raise the timeout and re-run.
  2. Treat this error as expected on interrupt: compare with errors.Is(ctx.Err(), context.Canceled) and skip logging it as a failure.
  3. Reduce the size of the copied tree (add .actignore / exclude paths) so collection finishes before the deadline.
Defensive patterns

Strategy: try-catch

Validate before calling

select {
case <-ctx.Done():
    return ctx.Err() // skip file collection entirely when already cancelled
default:
}
_ = collector.CollectFiles(ctx, nil)

Try / catch

err := exec(ctx)
if err != nil {
    if errors.Is(err, context.Canceled) || errors.Is(ctx.Err(), context.Canceled) || err.Error() == "copy cancelled" {
        return nil // treat interrupt as clean stop, not a failure
    }
    return err
}

Prevention

When it happens

Trigger: A job-level or global context timeout/interrupt (SIGINT, workflow cancellation, parent executor abort) fires while act is copying workspace files or preparing an upload, so the very next file visit returns this error.

Common situations: User hits Ctrl-C during artifact upload or workspace tar preparation; a job timeout cancels the context during cache save; test harnesses cancel the run context while file collection is in progress.

Related errors


AI-assisted analysis of nektos/act@4f41128141 (2026-08-15). Data as JSON: /api/errors/8549301c377419a8. Report an issue: GitHub.