nektos/act · error

Non-string path passed to hashFiles

Error message

Non-string path passed to hashFiles

What it means

Thrown by hashFiles() when filepath.Walk over the working directory returns an error (e.g. directory removed mid-walk, permission denied on a subdirectory, or the workspace path does not exist). The walk error is wrapped into this message.

Source

Thrown at pkg/exprparser/functions.go:198

	return data, nil
}

func (impl *interperterImpl) hashFiles(paths ...reflect.Value) (string, error) {
	var ps []gitignore.Pattern

	const cwdPrefix = "." + string(filepath.Separator)
	const excludeCwdPrefix = "!" + cwdPrefix
	for _, path := range paths {
		if path.Kind() == reflect.String {
			cleanPath := path.String()
			if strings.HasPrefix(cleanPath, cwdPrefix) {
				cleanPath = cleanPath[len(cwdPrefix):]
			} else if strings.HasPrefix(cleanPath, excludeCwdPrefix) {
				cleanPath = "!" + cleanPath[len(excludeCwdPrefix):]
			}
			ps = append(ps, gitignore.ParsePattern(cleanPath, nil))
		} else {
			return "", fmt.Errorf("Non-string path passed to hashFiles")
		}
	}

	matcher := gitignore.NewMatcher(ps)

	var files []string
	if err := filepath.Walk(impl.config.WorkingDir, func(path string, fi fs.FileInfo, err error) error {
		if err != nil {
			return err
		}
		sansPrefix := strings.TrimPrefix(path, impl.config.WorkingDir+string(filepath.Separator))
		parts := strings.Split(sansPrefix, string(filepath.Separator))
		if fi.IsDir() || !matcher.Match(parts, fi.IsDir()) {
			return nil
		}
		files = append(files, path)
		return nil
	}); err != nil {

View on GitHub (pinned to 4f41128141)

Solutions

  1. Add actions/checkout (or ensure the workspace exists) before evaluating hashFiles().
  2. Check the wrapped error for permission issues and fix filesystem permissions.
  3. Avoid hashFiles() in job-level expressions that run before any step.

Example fix

# before
jobs:
  build:
    if: hashFiles('src/**') != ''
    steps: [run: echo hi]
# after
jobs:
  build:
    steps:
      - uses: actions/checkout@v4
      - run: echo ${{ hashFiles('src/**') }}
Defensive patterns

Strategy: try-catch

Validate before calling

func workspaceWalkable(dir string) bool {
  fi, err := os.Stat(dir)
  return err == nil && fi.IsDir()
}

Try / catch

if h, err := hashFiles('src/**'); err != nil {
  if strings.Contains(err.Error(), 'filepath.Walk') {
    h = '' // no workspace yet: skip caching rather than fail
  } else { return err }
}

Prevention

When it happens

Trigger: Running hashFiles() in a job whose workspace was not checked out (no actions/checkout); directories with unreadable permissions; concurrent cleanup deleting files during evaluation.

Common situations: hashFiles() in a job-level if: or cache key before checkout runs; act run against a directory with restrictive perms; container jobs with missing bind mounts.

Related errors


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