{"record":{"id":"57d3bc3f87c0c415","repo":"anomalyco/sst","slug":"failed-to-scan-source-files-v","errorCode":null,"errorMessage":"failed to scan source files: %v","messagePattern":"failed to scan source files: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/runtime/python/python.go","lineNumber":286,"sourceCode":"\n\t\t// Skip hidden directories and common non-Python directories\n\t\tif info.IsDir() {\n\t\t\tif strings.HasPrefix(filepath.Base(path), \".\") ||\n\t\t\t\tstrings.Contains(relPath, \"node_modules\") ||\n\t\t\t\tstrings.Contains(relPath, \"__pycache__\") {\n\t\t\t\treturn filepath.SkipDir\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\n\t\tif strings.HasSuffix(path, \".py\") {\n\t\t\tsourceFiles[relPath] = info\n\t\t}\n\n\t\treturn nil\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to scan source files: %v\", err)\n\t}\n\n\t// Collect Python files in artifacts\n\tartifactFiles := make(map[string]os.FileInfo)\n\tif _, err := os.Stat(destDir); err == nil {\n\t\terr = filepath.Walk(destDir, func(path string, info os.FileInfo, err error) error {\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\trelPath, err := filepath.Rel(destDir, path)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tif !info.IsDir() && strings.HasSuffix(path, \".py\") {\n\t\t\t\tartifactFiles[relPath] = info\n\t\t\t}","sourceCodeStart":268,"sourceCodeEnd":304,"githubUrl":"https://github.com/anomalyco/sst/blob/a0bd20f762883e72a35caccb4896c42ce5b3f707/pkg/runtime/python/python.go#L268-L304","documentation":"Raised in syncPythonFiles (pkg/runtime/python/python.go:286) when filepath.Walk over the project root fails while collecting .py source files for artifact syncing in legacy workspace layouts. filepath.Walk reports errors for unreadable directories (permission denied) or files disappearing mid-walk, and the walk callback also propagates filepath.Rel failures.","triggerScenarios":"Project root or a subdirectory not readable by the sst process (permissions); a symlink loop or deleted directory during the walk; a file removed between listing and stat; filepath.Rel returning an error for a path not under srcDir.","commonSituations":"Docker container or CI running sst as a different user than the project owner; macOS/ Linux permission changes after syncing from another machine; editors/renames racing a live `sst dev` session on workspace-layout (package/src/package) Python projects.","solutions":["Read the wrapped error path: `chmod`/`chown` the named directory so the sst process can traverse it","Ensure you run sst from the project root that still exists (no renamed/deleted folders mid-dev); restart `sst dev`","Remove symlink loops or stale package/src/package remnants; avoid walking into .venv-like dirs with bad permissions"],"exampleFix":"// before\nsst dev -> failed to scan source files: open packages/api: permission denied\n// after\nsudo chown -R $(whoami) packages/api\nsst dev","handlingStrategy":"validation","validationCode":"// verify project tree is readable before running dev/deploy\nerr := filepath.Walk(projectRoot, func(p string, info os.FileInfo, err error) error {\n    if err != nil { return fmt.Errorf(\"unreadable: %s: %v\", p, err) }\n    return nil\n})\nif err != nil { fmt.Println(\"fix permissions before running sst:\", err) }","typeGuard":null,"tryCatchPattern":"if err := syncPythonFiles(src, dst); err != nil {\n    if strings.Contains(err.Error(), \"failed to scan source files\") {\n        // rescan after fixing permissions/restart to avoid mid-walk races\n        return resyncAfterPermissionsFix()\n    }\n    return err\n}","preventionTips":["Run sst as the same user that owns the project files (especially in Docker/CI)","Avoid deleting/renaming directories while `sst dev` is syncing","Break symlink loops; don't symlink .venv or caches into walked source trees","On shared machines keep project dirs with chmod u+rwX"],"tags":["filesystem","permissions","walk","python","sync"],"backgroundTag":"permission-denied","analyzedSha":"a0bd20f762883e72a35caccb4896c42ce5b3f707","analyzedAt":"2026-08-30T11:26:00.383Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}