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
- Add actions/checkout (or ensure the workspace exists) before evaluating hashFiles().
- Check the wrapped error for permission issues and fix filesystem permissions.
- 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
- Run actions/checkout before hashFiles
- Do not use hashFiles in job-level if: conditions
- Verify the working directory exists and is readable
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
- Unable to filepath.Walk: %v
- Unable to io.Copy: %v
- Invalid JSON: %v
- Unable to os.Open: %v
- --health-start-interval cannot be negative
AI-assisted analysis of nektos/act@4f41128141 (2026-08-15).
Data as JSON: /api/errors/cf3b8627ecd17721.
Report an issue: GitHub.