{"record":{"id":"c78e9101c4c47cfa","repo":"wavetermdev/waveterm","slug":"app-directory-does-not-exist-s","errorCode":null,"errorMessage":"app directory does not exist: %s","messagePattern":"app directory does not exist: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/waveappstore/waveappstore.go","lineNumber":452,"sourceCode":"\tif output, err := cmd.CombinedOutput(); err != nil {\n\t\treturn fmt.Errorf(\"gofmt failed: %w\\nOutput: %s\", err, string(output))\n\t}\n\n\treturn nil\n}\n\nfunc ListAllAppFiles(appId string) (*fileutil.ReadDirResult, error) {\n\tif err := ValidateAppId(appId); err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid appId: %w\", err)\n\t}\n\n\tappDir, err := GetAppDir(appId)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif _, err := os.Stat(appDir); os.IsNotExist(err) {\n\t\treturn nil, fmt.Errorf(\"app directory does not exist: %s\", appDir)\n\t}\n\n\treturn fileutil.ReadDirRecursive(appDir, 10000)\n}\n\nfunc ListAllApps() ([]wshrpc.AppInfo, error) {\n\thomeDir := wavebase.GetHomeDir()\n\twaveappsDir := filepath.Join(homeDir, \"waveapps\")\n\n\tif _, err := os.Stat(waveappsDir); os.IsNotExist(err) {\n\t\treturn []wshrpc.AppInfo{}, nil\n\t}\n\n\tnamespaces, err := os.ReadDir(waveappsDir)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to read waveapps directory: %w\", err)\n\t}\n","sourceCodeStart":434,"sourceCodeEnd":470,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/waveappstore/waveappstore.go#L434-L470","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Verify the app exists by calling ListAllApps or os.Stat(GetAppDir(appId)) before listing files","Recreate the app (or its directory) if it was deleted unintentionally","Reconnect/remount the volume holding ~/waveapps if it is on an external mount","Refresh the frontend app list so stale appIds are not passed to the API"],"exampleFix":"// before\nfiles, err := ListAllAppFiles(appId)\n// after\nappDir, _ := GetAppDir(appId)\nif _, err := os.Stat(appDir); os.IsNotExist(err) {\n    return fmt.Errorf(\"app %s not found; refresh app list\", appId)\n}\nfiles, err := ListAllAppFiles(appId)","handlingStrategy":"fallback","validationCode":"appDir, err := GetAppDir(appId)\nif err != nil {\n\treturn err\n}\nif _, err := os.Stat(appDir); os.IsNotExist(err) {\n\treturn fmt.Errorf(\"app %s does not exist; create it or refresh the app list\", appId)\n}","typeGuard":null,"tryCatchPattern":"files, err := ListAllAppFiles(appId)\nif err != nil {\n\tif strings.Contains(err.Error(), \"app directory does not exist\") {\n\t\treturn &AppNotFoundError{AppId: appId} // treat as empty list or recreate\n\t}\n\treturn err\n}","preventionTips":["Refresh the app list after delete/publish operations to purge stale appIds","Confirm the app was created before listing its files","Check that any external mount hosting ~/waveapps is connected"],"tags":["filesystem","go","missing-resource"],"backgroundTag":"directory-not-found","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}