wavetermdev/waveterm · error
failed to check draft app: %w
Error message
failed to check draft app: %w
What it means
Same check as the local variant, but for the old draft directory. If os.Stat(oldDraftDir) fails with anything other than NotExist, RenameLocalApp returns "failed to check draft app: %w" so transient/permission errors are not misread as 'app does not exist'.
Source
Thrown at pkg/waveappstore/waveappstore.go:679
oldLocalDir := filepath.Join(waveappsDir, AppNSLocal, appName)
newLocalDir := filepath.Join(waveappsDir, AppNSLocal, newAppName)
oldDraftDir := filepath.Join(waveappsDir, AppNSDraft, appName)
newDraftDir := filepath.Join(waveappsDir, AppNSDraft, newAppName)
// Check if at least one of the apps exists
localExists := false
draftExists := false
if _, err := os.Stat(oldLocalDir); err == nil {
localExists = true
} else if !os.IsNotExist(err) {
return fmt.Errorf("failed to check local app: %w", err)
}
if _, err := os.Stat(oldDraftDir); err == nil {
draftExists = true
} else if !os.IsNotExist(err) {
return fmt.Errorf("failed to check draft app: %w", err)
}
if !localExists && !draftExists {
return fmt.Errorf("app '%s' does not exist in local or draft namespace", appName)
}
// Check if new app name already exists in either namespace
if _, err := os.Stat(newLocalDir); err == nil {
return fmt.Errorf("local app '%s' already exists", newAppName)
} else if !os.IsNotExist(err) {
return fmt.Errorf("failed to check if new local app exists: %w", err)
}
if _, err := os.Stat(newDraftDir); err == nil {
return fmt.Errorf("draft app '%s' already exists", newAppName)
} else if !os.IsNotExist(err) {
return fmt.Errorf("failed to check if new draft app exists: %w", err)
}View on GitHub (pinned to a4447c1563)
Solutions
- Check and fix permissions on ~/waveapps/draft and its contents
- Confirm the filesystem is writable/mounted and the disk is healthy
- Remount or restart if the filesystem is in a bad state
Defensive patterns
Strategy: try-catch
Validate before calling
draftDir := filepath.Join(wavebase.GetHomeDir(), "waveapps", "draft")
if err := os.Access(draftDir, os.R_OK); err != nil {
return fmt.Errorf("no read access to draft dir: %w", err)
} Try / catch
if err := waveappstore.RenameLocalApp(oldName, newName); err != nil {
if strings.Contains(err.Error(), "failed to check draft app") {
// surface as an environment/permissions problem, not 'app missing'
return fmt.Errorf("cannot read draft dir: %w", err)
}
return err
} Prevention
- Keep ~/waveapps/draft readable/writable by the app user
- Watch for read-only remounts after crashes and remount rw
- Avoid changing ownership of the waveapps tree out from under the process
When it happens
Trigger: os.Stat(oldDraftDir) returns a non-ENOENT error: unreadable draft directory, permission denied on parents, or I/O failure.
Common situations: Permission changes under ~/waveapps/draft, draft directory owned by another user, disk errors or a read-only filesystem after a crash.
Related errors
- failed to check local app: %w
- failed to check if new local app exists: %w
- failed to create backup directory: %w
- failed to create socket directory: %w
- failed to create log directory: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/e6be463a4fe90c19.
Report an issue: GitHub.