wavetermdev/waveterm · error
failed to get app directory: %w
Error message
failed to get app directory: %w
What it means
buildAndRun wraps the error from waveappstore.GetAppDir(appId), which resolves the on-disk directory for the given app id. The controller throws this when the app id cannot be mapped to a valid app directory (e.g. the app is not installed / its directory does not exist). It aborts the build-and-run pipeline before any build steps run.
Source
Thrown at pkg/buildercontroller/buildercontroller.go:202
defer func() {
panichandler.PanicHandler(fmt.Sprintf("buildercontroller[%s].buildAndRun", bc.builderId), recover())
}()
bc.buildAndRun(buildCtx, appId, builderEnv, nil)
}()
return nil
}
func (bc *BuilderController) buildAndRun(ctx context.Context, appId string, builderEnv map[string]string, resultCh chan<- *BuildResult) {
appNS, _, err := waveappstore.ParseAppId(appId)
if err != nil {
bc.handleBuildError(fmt.Errorf("failed to parse app id: %w", err), resultCh)
return
}
appPath, err := waveappstore.GetAppDir(appId)
if err != nil {
bc.handleBuildError(fmt.Errorf("failed to get app directory: %w", err), resultCh)
return
}
cachePath, err := GetBuilderAppExecutablePath(appPath)
if err != nil {
bc.handleBuildError(fmt.Errorf("failed to get builder executable path: %w", err), resultCh)
return
}
nodePath := wavebase.GetWaveAppElectronExecPath()
if nodePath == "" {
bc.handleBuildError(fmt.Errorf("electron executable path not set"), resultCh)
return
}
scaffoldPath := waveapputil.GetTsunamiScaffoldPath()
settings := wconfig.GetWatcher().GetFullConfig().Settings
sdkReplacePath := settings.TsunamiSdkReplacePathView on GitHub (pinned to a4447c1563)
Solutions
- Verify the appId exists by checking its app directory under the waveappstore before triggering a build
- Reinstall or re-scaffold the app so GetAppDir finds a valid directory
- Confirm the appId string is well-formed (ParseAppId already succeeded, so check for storage-level issues like permissions)
- Check disk state / wavebase wave home directory for corruption
Example fix
// before
bc.buildAndRun(ctx, "myapp", env, resultCh) // app never installed
// after
if _, err := os.Stat(waveappstore.GetAppDirMust("myapp")); err == nil {
bc.buildAndRun(ctx, "myapp", env, resultCh)
} Defensive patterns
Strategy: validation
Validate before calling
if _, err := os.Stat(waveappstore.GetAppDirMust(appId)); err != nil {
return fmt.Errorf("app %q not installed: %w", appId, err)
} Type guard
func appExists(appId string) bool {
_, err := os.Stat(waveappstore.GetAppDirMust(appId))
return err == nil
} Try / catch
if err := runBuild(appId); err != nil {
var target *AppNotInstalledError
if errors.As(err, &target) { /* reinstall app */ }
} Prevention
- Always install/scaffold the app before triggering a build
- Validate the appId against the app store list first
- Don't delete app directories while builds may be in flight
When it happens
Trigger: Calling BuilderController build/run (e.g. via RPC) with an appId that was never installed, or whose app directory was deleted from the waveappstore while a build was requested; also triggered when GetAppDir rejects a malformed or non-canonical appId path.
Common situations: User removes/reinstalls the app while the builder is asked to run it; stale app id cached in the frontend; app directory wiped by a cache cleanup; appId with illegal path characters.
Related errors
- failed to get builder executable path: %w
- build output not found: %w
- failed to run app: %w
- failed to read app manifest: %w
- failed to stat file for backup: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/aecea9afec6833c2.
Report an issue: GitHub.