{"record":{"id":"4094a17018a56161","repo":"nektos/act","slug":"unable-to-io-copy-v","errorCode":null,"errorMessage":"Unable to io.Copy: %v","messagePattern":"Unable to io\\.Copy: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/exprparser/functions.go","lineNumber":233,"sourceCode":"\t\treturn nil\n\t}); err != nil {\n\t\treturn \"\", fmt.Errorf(\"Unable to filepath.Walk: %v\", err)\n\t}\n\n\tif len(files) == 0 {\n\t\treturn \"\", nil\n\t}\n\n\thasher := sha256.New()\n\n\tfor _, file := range files {\n\t\tf, err := os.Open(file)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"Unable to os.Open: %v\", err)\n\t\t}\n\n\t\tif _, err := io.Copy(hasher, f); err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"Unable to io.Copy: %v\", err)\n\t\t}\n\n\t\tif err := f.Close(); err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"Unable to Close file: %v\", err)\n\t\t}\n\t}\n\n\treturn hex.EncodeToString(hasher.Sum(nil)), nil\n}\n\nfunc (impl *interperterImpl) getNeedsTransitive(job *model.Job) []string {\n\tneeds := job.Needs()\n\n\tfor _, need := range needs {\n\t\tparentNeeds := impl.getNeedsTransitive(impl.config.Run.Workflow.GetJob(need))\n\t\tneeds = append(needs, parentNeeds...)\n\t}\n","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/nektos/act/blob/4f411281417e88660bea1c1a1749aa71ae0bd60f/pkg/exprparser/functions.go#L215-L251","documentation":"Thrown by hashFiles() when closing a successfully hashed file fails. Rare — usually indicates a deferred filesystem error (NFS close semantics, file already deleted, descriptor issues). The hash computation itself already succeeded.","triggerScenarios":"Hashing files on network filesystems where close() reports stale writes; files deleted between open and close; file-descriptor exhaustion surfacing at close.","commonSituations":"Workspaces on NFS/SMB mounts inside act; huge trees where ulimit -n is reached; aggressive concurrent cleanup jobs.","solutions":["Move the workspace to a local filesystem.","Raise the open-file limit (ulimit -n) if hashing many files.","Narrow patterns to reduce the number of opened files.","Retry the run once — transient FS conditions often clear."],"exampleFix":"# shell\n# before\nulimit -n 1024\nact -j build\n# after\nulimit -n 65536\nact -j build","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if _, err := hashFiles(p...); err != nil {\n  if strings.Contains(err.Error(), 'Close file') {\n    log.Warn('close failed after successful hash; treating as non-fatal')\n    err = nil\n  }\n}","preventionTips":["Raise ulimit -n when hashing large trees","Prefer local filesystems over NFS for workspaces","Narrow patterns to reduce opened file count"],"tags":["expressions","hash-files","filesystem","file-descriptors"],"backgroundTag":null,"analyzedSha":"4f411281417e88660bea1c1a1749aa71ae0bd60f","analyzedAt":"2026-08-15T09:19:46.307Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}