wavetermdev/waveterm · error

app directory does not exist: %s

Error message

app directory does not exist: %s

What it means

After validating the appId and computing ~/waveapps/<ns>/<appName>, ListAllAppFiles checks os.Stat on the app directory. If the directory does not exist, it returns "app directory does not exist" rather than attempting a recursive read. Note ListAllApps deliberately returns an empty list for a missing waveapps root, but per-app listing treats a missing app as an error.

Source

Thrown at pkg/waveappstore/waveappstore.go:452

	if output, err := cmd.CombinedOutput(); err != nil {
		return fmt.Errorf("gofmt failed: %w\nOutput: %s", err, string(output))
	}

	return nil
}

func ListAllAppFiles(appId string) (*fileutil.ReadDirResult, 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
	}

	if _, err := os.Stat(appDir); os.IsNotExist(err) {
		return nil, fmt.Errorf("app directory does not exist: %s", appDir)
	}

	return fileutil.ReadDirRecursive(appDir, 10000)
}

func ListAllApps() ([]wshrpc.AppInfo, error) {
	homeDir := wavebase.GetHomeDir()
	waveappsDir := filepath.Join(homeDir, "waveapps")

	if _, err := os.Stat(waveappsDir); os.IsNotExist(err) {
		return []wshrpc.AppInfo{}, nil
	}

	namespaces, err := os.ReadDir(waveappsDir)
	if err != nil {
		return nil, fmt.Errorf("failed to read waveapps directory: %w", err)
	}

View on GitHub (pinned to a4447c1563)

Solutions

  1. Verify the app exists by calling ListAllApps or os.Stat(GetAppDir(appId)) before listing files
  2. Recreate the app (or its directory) if it was deleted unintentionally
  3. Reconnect/remount the volume holding ~/waveapps if it is on an external mount
  4. Refresh the frontend app list so stale appIds are not passed to the API

Example fix

// before
files, err := ListAllAppFiles(appId)
// after
appDir, _ := GetAppDir(appId)
if _, err := os.Stat(appDir); os.IsNotExist(err) {
    return fmt.Errorf("app %s not found; refresh app list", appId)
}
files, err := ListAllAppFiles(appId)
Defensive patterns

Strategy: fallback

Validate before calling

appDir, err := GetAppDir(appId)
if err != nil {
	return err
}
if _, err := os.Stat(appDir); os.IsNotExist(err) {
	return fmt.Errorf("app %s does not exist; create it or refresh the app list", appId)
}

Try / catch

files, err := ListAllAppFiles(appId)
if err != nil {
	if strings.Contains(err.Error(), "app directory does not exist") {
		return &AppNotFoundError{AppId: appId} // treat as empty list or recreate
	}
	return err
}

Prevention

When it happens

Trigger: Listing files for an appId that was never created, was deleted (DeleteApp/RemoveApp), or whose directory was removed manually — while other files for the namespace still exist.

Common situations: Stale UI state referencing a deleted app; a typo in the app name so a nonexistent directory is probed; apps stored on a removable/network mount that is currently disconnected; publishing/draft lifecycle where a draft folder was already published and removed.

Related errors


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