{"record":{"id":"e6a5c4935517f0ca","repo":"anomalyco/sst","slug":"failed-to-hash-file-w","errorCode":null,"errorMessage":"failed to hash file: %w","messagePattern":"failed to hash file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/runtime/python/python.go","lineNumber":464,"sourceCode":"\t\tdstPath := filepath.Join(dst, relPath)\n\t\tif info.IsDir() {\n\t\t\treturn os.MkdirAll(dstPath, info.Mode())\n\t\t}\n\t\treturn copyFile(p, dstPath)\n\t})\n}\n\n// hashFileContents computes a SHA256 hash of a file's contents.\nfunc hashFileContents(filePath string) (string, error) {\n\tfile, err := os.Open(filePath)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to open file for hashing: %w\", err)\n\t}\n\tdefer file.Close()\n\n\thasher := sha256.New()\n\tif _, err := io.Copy(hasher, file); err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to hash file: %w\", err)\n\t}\n\n\treturn hex.EncodeToString(hasher.Sum(nil)), nil\n}\n\n// hasWorkspaceLayoutPatterns checks for package/src/package patterns that need flattening.\n// Scans up to one level below projectRoot to cover both single-package and monorepo layouts.\nfunc (r *PythonRuntime) hasWorkspaceLayoutPatterns(projectRoot string) bool {\n\tvar scan func(dir string, depth int) bool\n\tscan = func(dir string, depth int) bool {\n\t\tentries, err := os.ReadDir(dir)\n\t\tif err != nil {\n\t\t\treturn false\n\t\t}\n\t\tfor _, entry := range entries {\n\t\t\tname := entry.Name()\n\t\t\tif !entry.IsDir() || strings.HasPrefix(name, \".\") || name == \"__pycache__\" || name == \"node_modules\" {\n\t\t\t\tcontinue","sourceCodeStart":446,"sourceCodeEnd":482,"githubUrl":"https://github.com/anomalyco/sst/blob/a0bd20f762883e72a35caccb4896c42ce5b3f707/pkg/runtime/python/python.go#L446-L482","documentation":"hashFileContents wraps io.Copy into the sha256 hasher with this message. The file opened fine, but reading its bytes into the hasher failed — an I/O error on read. Thrown from copySyncedDependencies during dev-mode change detection.","triggerScenarios":"io.Copy(hasher, file) errors while hashing a synced dependency: source file on flaky/networked storage, file truncated by a concurrent writer mid-hash, or a special file that errors on read.","commonSituations":"Hashing files on an NFS/EFS mount that hiccups; another process (formatter, package manager) rewriting the file concurrently during `sst dev`; sparse or damaged file with underlying block errors.","solutions":["Re-run the sync — transient I/O errors usually clear","Check dmesg/OS logs for underlying disk or network filesystem errors","Avoid hashing while package managers rewrite the same files (pause/lock concurrent processes)","Copy to local temp storage before hashing if files live on remote mounts"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"null","typeGuard":null,"tryCatchPattern":"if err := sstDev(); err != nil {\n\tif strings.Contains(err.Error(), \"failed to hash file\") {\n\t\t// transient read I/O error: wait and re-run sync\n\t}\n}","preventionTips":["Keep hashed files on local storage, not networked mounts, when possible","Lock or pause concurrent writers during dependency hashing","Check OS logs for disk errors if it recurs","Retry hashing before failing the sync"],"tags":["go","filesystem","hashing","io"],"backgroundTag":"file-copy-failed","analyzedSha":"a0bd20f762883e72a35caccb4896c42ce5b3f707","analyzedAt":"2026-08-30T11:26:00.383Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}