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.TsunamiSdkReplacePath

View on GitHub (pinned to a4447c1563)

Solutions

  1. Verify the appId exists by checking its app directory under the waveappstore before triggering a build
  2. Reinstall or re-scaffold the app so GetAppDir finds a valid directory
  3. Confirm the appId string is well-formed (ParseAppId already succeeded, so check for storage-level issues like permissions)
  4. 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

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


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