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

  1. Verify the path exists: `ls -ld <path>`; fix typos and casing.
  2. Print or log the absolute working directory and make the path absolute to rule out cwd surprises.
  3. Check execute (x) permission on every parent directory of the path.
  4. 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

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


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/c3a93e2355ac77ad. Report an issue: GitHub.