wavetermdev/waveterm · error

local app '%s' already exists

Error message

local app '%s' already exists

What it means

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.

Source

Thrown at pkg/waveappstore/waveappstore.go:688

	if _, err := os.Stat(oldLocalDir); err == nil {
		localExists = true
	} else if !os.IsNotExist(err) {
		return fmt.Errorf("failed to check local app: %w", err)
	}

	if _, err := os.Stat(oldDraftDir); err == nil {
		draftExists = true
	} else if !os.IsNotExist(err) {
		return fmt.Errorf("failed to check draft app: %w", err)
	}

	if !localExists && !draftExists {
		return fmt.Errorf("app '%s' does not exist in local or draft namespace", appName)
	}

	// Check if new app name already exists in either namespace
	if _, err := os.Stat(newLocalDir); err == nil {
		return fmt.Errorf("local app '%s' already exists", newAppName)
	} else if !os.IsNotExist(err) {
		return fmt.Errorf("failed to check if new local app exists: %w", err)
	}

	if _, err := os.Stat(newDraftDir); err == nil {
		return fmt.Errorf("draft app '%s' already exists", newAppName)
	} else if !os.IsNotExist(err) {
		return fmt.Errorf("failed to check if new draft app exists: %w", err)
	}

	// Rename local app if it exists
	if localExists {
		if err := os.Rename(oldLocalDir, newLocalDir); err != nil {
			return fmt.Errorf("failed to rename local app: %w", err)
		}
	}

	// Rename draft app if it exists

View on GitHub (pinned to a4447c1563)

Solutions

  1. Pick a different newName that is not already used in the local namespace
  2. If the destination is a leftover of a failed rename, remove it manually first
  3. List existing local apps and choose a unique name

Example fix

// before
RenameLocalApp("myapp", "existing") // local:existing installed
// after
RenameLocalApp("myapp", "existing-v2")
Defensive patterns

Strategy: validation

Validate before calling

func localNameTaken(name string) bool {
    _, err := os.Stat(filepath.Join(wavebase.GetHomeDir(), "waveapps", "local", name))
    return err == nil
}
// require !localNameTaken(newName) before renaming

Try / catch

if err := waveappstore.RenameLocalApp(oldName, newName); err != nil {
    if strings.Contains(err.Error(), "already exists") {
        newName = newName + "-2"
        return waveappstore.RenameLocalApp(oldName, newName)
    }
    return err
}

Prevention

When it happens

Trigger: Calling RenameLocalApp(oldName, newName) where ~/waveapps/local/<newName> already exists — e.g. renaming onto an installed app or retrying a partially completed rename.

Common situations: 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.

Related errors


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