{"record":{"id":"ed5b620b9ec0367e","repo":"wavetermdev/waveterm","slug":"local-app-s-already-exists","errorCode":null,"errorMessage":"local app '%s' already exists","messagePattern":"local app '(.+?)' already exists","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/waveappstore/waveappstore.go","lineNumber":688,"sourceCode":"\tif _, err := os.Stat(oldLocalDir); err == nil {\n\t\tlocalExists = true\n\t} else if !os.IsNotExist(err) {\n\t\treturn fmt.Errorf(\"failed to check local app: %w\", err)\n\t}\n\n\tif _, err := os.Stat(oldDraftDir); err == nil {\n\t\tdraftExists = true\n\t} else if !os.IsNotExist(err) {\n\t\treturn fmt.Errorf(\"failed to check draft app: %w\", err)\n\t}\n\n\tif !localExists && !draftExists {\n\t\treturn fmt.Errorf(\"app '%s' does not exist in local or draft namespace\", appName)\n\t}\n\n\t// Check if new app name already exists in either namespace\n\tif _, err := os.Stat(newLocalDir); err == nil {\n\t\treturn fmt.Errorf(\"local app '%s' already exists\", newAppName)\n\t} else if !os.IsNotExist(err) {\n\t\treturn fmt.Errorf(\"failed to check if new local app exists: %w\", err)\n\t}\n\n\tif _, err := os.Stat(newDraftDir); err == nil {\n\t\treturn fmt.Errorf(\"draft app '%s' already exists\", newAppName)\n\t} else if !os.IsNotExist(err) {\n\t\treturn fmt.Errorf(\"failed to check if new draft app exists: %w\", err)\n\t}\n\n\t// Rename local app if it exists\n\tif localExists {\n\t\tif err := os.Rename(oldLocalDir, newLocalDir); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to rename local app: %w\", err)\n\t\t}\n\t}\n\n\t// Rename draft app if it exists","sourceCodeStart":670,"sourceCodeEnd":706,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/waveappstore/waveappstore.go#L670-L706","documentation":"To keep renames unambiguous, RenameLocalApp rejects the operation if the destination already exists in the local namespace. If os.Stat(newLocalDir) succeeds, the new name is taken and the error \"local app '%s' already exists\" is returned before any move happens.","triggerScenarios":"Calling RenameLocalApp(oldName, newName) where ~/waveapps/local/<newName> already exists — e.g. renaming onto an installed app or retrying a partially completed rename.","commonSituations":"Choosing a name that collides with an existing installed app, running the same rename twice after a first partial success, installing the target name between generating and applying the rename.","solutions":["Pick a different newName that is not already used in the local namespace","If the destination is a leftover of a failed rename, remove it manually first","List existing local apps and choose a unique name"],"exampleFix":"// before\nRenameLocalApp(\"myapp\", \"existing\") // local:existing installed\n// after\nRenameLocalApp(\"myapp\", \"existing-v2\")","handlingStrategy":"validation","validationCode":"func localNameTaken(name string) bool {\n    _, err := os.Stat(filepath.Join(wavebase.GetHomeDir(), \"waveapps\", \"local\", name))\n    return err == nil\n}\n// require !localNameTaken(newName) before renaming","typeGuard":null,"tryCatchPattern":"if err := waveappstore.RenameLocalApp(oldName, newName); err != nil {\n    if strings.Contains(err.Error(), \"already exists\") {\n        newName = newName + \"-2\"\n        return waveappstore.RenameLocalApp(oldName, newName)\n    }\n    return err\n}","preventionTips":["Generate unique target names (suffix with timestamp/version)","List existing local apps before proposing a rename target","Make renames idempotent: skip if oldName no longer exists and newName does"],"tags":["go","rename","conflict","waveappstore"],"backgroundTag":"name-already-exists","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}