wavetermdev/waveterm · error
failed to stat file: %w
Error message
failed to stat file: %w
What it means
ReadAppFile calls os.Stat on the resolved file path to get the modification time before reading. This error wraps a failed os.Stat (waveappstore.go:304-307). The dominant case is the file not existing (fs.ErrNotExist); it can also be a permission problem on a parent directory.
Source
Thrown at pkg/waveappstore/waveappstore.go:306
func ReadAppFile(appId string, fileName string) (*FileData, error) {
if err := ValidateAppId(appId); err != nil {
return nil, fmt.Errorf("invalid appId: %w", err)
}
appDir, err := GetAppDir(appId)
if err != nil {
return nil, err
}
filePath, err := validateAndResolveFilePath(appDir, fileName)
if err != nil {
return nil, err
}
fileInfo, err := os.Stat(filePath)
if err != nil {
return nil, fmt.Errorf("failed to stat file: %w", err)
}
contents, err := os.ReadFile(filePath)
if err != nil {
return nil, fmt.Errorf("failed to read file: %w", err)
}
return &FileData{
Contents: contents,
ModTs: fileInfo.ModTime().UnixMilli(),
}, nil
}
func DeleteAppFile(appId string, fileName string) error {
if err := ValidateAppId(appId); err != nil {
return fmt.Errorf("invalid appId: %w", err)
}
View on GitHub (pinned to a4447c1563)
Solutions
- Check the wrapped error with errors.Is(err, fs.ErrNotExist) and treat it as 'file missing' rather than a hard failure.
- Verify the app exists first (waveappstore.ListAllAppFiles or os.Stat on waveappstore.GetAppDir(appId)).
- Confirm the namespace: 'draft/myapp' and 'local/myapp' are separate directories; the file may only exist in one.
- Fix the fileName spelling; path names are case-sensitive on Linux.
Example fix
// before
data, err := waveappstore.ReadAppFile(appId, fileName)
if err != nil { return err } // treats missing file as fatal
// after
data, err := waveappstore.ReadAppFile(appId, fileName)
if err != nil {
if errors.Is(err, fs.ErrNotExist) {
return nil, nil // file not written yet — handle as empty
}
return err
} Defensive patterns
Strategy: try-catch
Validate before calling
func fileExists(appId, fileName string) bool {
dir, err := waveappstore.GetAppDir(appId)
if err != nil { return false }
_, err = os.Stat(filepath.Join(dir, filepath.Clean(fileName)))
return err == nil
} Try / catch
data, err := waveappstore.ReadAppFile(appId, fileName)
if err != nil {
if errors.Is(err, fs.ErrNotExist) {
return nil, nil // treat as absent
}
return nil, err
} Prevention
- Check the app exists (ListAllAppFiles) before reading individual files.
- Be explicit about namespace: draft files are separate from local files.
- Verify file name spelling and case.
- Treat fs.ErrNotExist as a normal 'not yet created' state, not a crash.
When it happens
Trigger: Calling ReadAppFile (or ReadAppFileCommand, generateBuilderAppData) for a fileName that does not exist inside the app directory, an app directory that does not exist yet, or a path whose parent dirs are unreadable.
Common situations: Reading a file from an app that was never created or was deleted; a typo in the file name; checking a file before WriteAppFile ever ran; reading across namespaces (draft vs local) where the file only exists in the other one.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- failed to delete file: %w
- accessing file %s: %w
- file does not exist: %q
- cannot access image file: %v
- failed to get app directory: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/67d1eadbc0e5685c.
Report an issue: GitHub.