wavetermdev/waveterm · error
failed to stat path: %w
Error message
failed to stat path: %w
What it means
After expanding the path, ReadDir calls os.Stat; any stat failure (most commonly a nonexistent path) is wrapped as 'failed to stat path'. The OS-level cause (ENOENT, EACCES, ENOTDIR) is preserved via %w. ReadDir requires an existing, statable path before it can proceed.
Source
Thrown at pkg/util/fileutil/readdir.go:46
type ReadDirResult struct {
Path string `json:"path"`
AbsolutePath string `json:"absolute_path"`
ParentDir string `json:"parent_dir,omitempty"`
Entries []DirEntryOut `json:"entries"`
EntryCount int `json:"entry_count"`
TotalEntries int `json:"total_entries"`
Truncated bool `json:"truncated,omitempty"`
}
func ReadDir(path string, maxEntries int) (*ReadDirResult, error) {
expandedPath, err := wavebase.ExpandHomeDir(path)
if err != nil {
return nil, fmt.Errorf("failed to expand path: %w", err)
}
fileInfo, err := os.Stat(expandedPath)
if err != nil {
return nil, fmt.Errorf("failed to stat path: %w", err)
}
if !fileInfo.IsDir() {
return nil, fmt.Errorf("path is not a directory")
}
entries, err := os.ReadDir(expandedPath)
if err != nil {
return nil, fmt.Errorf("failed to read directory: %w", err)
}
totalEntries := len(entries)
isDirMap := make(map[string]bool)
symlinkCount := 0
for _, entry := range entries {
name := entry.Name()
if entry.Type()&fs.ModeSymlink != 0 {View on GitHub (pinned to a4447c1563)
Solutions
- Verify the path exists: `ls -ld <path>`; fix typos and casing.
- Print or log the absolute working directory and make the path absolute to rule out cwd surprises.
- Check execute (x) permission on every parent directory of the path.
- Create the directory first if it is expected to exist (`os.MkdirAll`).
Example fix
// before
fileutil.ReadDir("./out/dist", 100) // run from wrong cwd
// after
fileutil.ReadDir("/home/user/project/out/dist", 100) Defensive patterns
Strategy: validation
Validate before calling
abs, err := filepath.Abs(path)
if err != nil { return err }
if _, err := os.Stat(abs); err != nil {
return fmt.Errorf("path %s does not exist: %w", abs, err)
} Type guard
func pathExists(path string) bool {
_, err := os.Stat(path)
return err == nil
} Try / catch
res, err := fileutil.ReadDir(path, max)
if err != nil {
if errors.Is(errors.Unwrap(err), fs.ErrNotExist) {
// create, prompt, or skip
}
return err
} Prevention
- Convert relative paths to absolute early, anchored to a known base directory.
- Log resolved absolute paths to catch cwd assumptions.
- On Linux, remember path casing is significant.
When it happens
Trigger: Calling ReadDir with a path that does not exist, is misspelled, sits under a non-directory component, or is unreadable due to permissions on a parent directory.
Common situations: Typo in the directory name; relative path resolved against an unexpected working directory; directory removed by a build/clean step; sandboxed agent lacking permission to traverse a parent dir; case-sensitive filesystem mismatch (LogS vs logs on Linux).
Related errors
- failed to expand path: %w
- path is not a directory
- getting absolute path for %s: %w
- %s: no such file
- chat not found: %s
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/c3a93e2355ac77ad.
Report an issue: GitHub.