{"record":{"id":"aecea9afec6833c2","repo":"wavetermdev/waveterm","slug":"failed-to-get-app-directory-w","errorCode":null,"errorMessage":"failed to get app directory: %w","messagePattern":"failed to get app directory: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/buildercontroller/buildercontroller.go","lineNumber":202,"sourceCode":"\t\tdefer func() {\n\t\t\tpanichandler.PanicHandler(fmt.Sprintf(\"buildercontroller[%s].buildAndRun\", bc.builderId), recover())\n\t\t}()\n\t\tbc.buildAndRun(buildCtx, appId, builderEnv, nil)\n\t}()\n\n\treturn nil\n}\n\nfunc (bc *BuilderController) buildAndRun(ctx context.Context, appId string, builderEnv map[string]string, resultCh chan<- *BuildResult) {\n\tappNS, _, err := waveappstore.ParseAppId(appId)\n\tif err != nil {\n\t\tbc.handleBuildError(fmt.Errorf(\"failed to parse app id: %w\", err), resultCh)\n\t\treturn\n\t}\n\n\tappPath, err := waveappstore.GetAppDir(appId)\n\tif err != nil {\n\t\tbc.handleBuildError(fmt.Errorf(\"failed to get app directory: %w\", err), resultCh)\n\t\treturn\n\t}\n\n\tcachePath, err := GetBuilderAppExecutablePath(appPath)\n\tif err != nil {\n\t\tbc.handleBuildError(fmt.Errorf(\"failed to get builder executable path: %w\", err), resultCh)\n\t\treturn\n\t}\n\n\tnodePath := wavebase.GetWaveAppElectronExecPath()\n\tif nodePath == \"\" {\n\t\tbc.handleBuildError(fmt.Errorf(\"electron executable path not set\"), resultCh)\n\t\treturn\n\t}\n\n\tscaffoldPath := waveapputil.GetTsunamiScaffoldPath()\n\tsettings := wconfig.GetWatcher().GetFullConfig().Settings\n\tsdkReplacePath := settings.TsunamiSdkReplacePath","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/buildercontroller/buildercontroller.go#L184-L220","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nbc.buildAndRun(ctx, \"myapp\", env, resultCh) // app never installed\n// after\nif _, err := os.Stat(waveappstore.GetAppDirMust(\"myapp\")); err == nil {\n    bc.buildAndRun(ctx, \"myapp\", env, resultCh)\n}","handlingStrategy":"validation","validationCode":"if _, err := os.Stat(waveappstore.GetAppDirMust(appId)); err != nil {\n    return fmt.Errorf(\"app %q not installed: %w\", appId, err)\n}","typeGuard":"func appExists(appId string) bool {\n    _, err := os.Stat(waveappstore.GetAppDirMust(appId))\n    return err == nil\n}","tryCatchPattern":"if err := runBuild(appId); err != nil {\n    var target *AppNotInstalledError\n    if errors.As(err, &target) { /* reinstall app */ }\n}","preventionTips":["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"],"tags":["go","filesystem","builder"],"backgroundTag":"app-directory-not-found","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}