wavetermdev/waveterm · error

invalid new app name: %w

Error message

invalid new app name: %w

What it means

RenameLocalApp validates the NEW app name the same way as the old one, wrapping ValidateAppId failures as "invalid new app name: %w". The rename is refused before any directory is moved so the destination path is guaranteed well-formed.

Source

Thrown at pkg/waveappstore/waveappstore.go:656

	return true, nil
}

// RenameLocalApp renames a local app by renaming its directories in both the local and draft namespaces.
// It takes the current app name and the new app name (without namespace prefixes).
// Both local/[appName] and draft/[appName] will be renamed if they exist.
// Returns an error if the app doesn't exist in either namespace, if the new name is invalid,
// or if the new name conflicts with an existing app.
func RenameLocalApp(appName string, newAppName string) error {
	// Validate the old app name by constructing a valid appId
	oldLocalAppId := MakeAppId(AppNSLocal, appName)
	if err := ValidateAppId(oldLocalAppId); err != nil {
		return fmt.Errorf("invalid app name: %w", err)
	}

	// Validate the new app name by constructing a valid appId
	newLocalAppId := MakeAppId(AppNSLocal, newAppName)
	if err := ValidateAppId(newLocalAppId); err != nil {
		return fmt.Errorf("invalid new app name: %w", err)
	}

	homeDir := wavebase.GetHomeDir()
	waveappsDir := filepath.Join(homeDir, "waveapps")

	oldLocalDir := filepath.Join(waveappsDir, AppNSLocal, appName)
	newLocalDir := filepath.Join(waveappsDir, AppNSLocal, newAppName)
	oldDraftDir := filepath.Join(waveappsDir, AppNSDraft, appName)
	newDraftDir := filepath.Join(waveappsDir, AppNSDraft, newAppName)

	// Check if at least one of the apps exists
	localExists := false
	draftExists := false
	if _, err := os.Stat(oldLocalDir); err == nil {
		localExists = true
	} else if !os.IsNotExist(err) {
		return fmt.Errorf("failed to check local app: %w", err)
	}

View on GitHub (pinned to a4447c1563)

Solutions

  1. Ensure the second argument is a bare, valid app name (no namespace prefix or invalid characters)
  2. Trim whitespace and reject empty strings before calling
  3. Pre-validate with ValidateAppId(MakeAppId(AppNSLocal, newName)) to see the wrapped cause

Example fix

// before
RenameLocalApp("myapp", "")
// after
newName := strings.TrimSpace(input)
if newName != "" { err := RenameLocalApp("myapp", newName) }
Defensive patterns

Strategy: validation

Validate before calling

func validNewName(name string) error {
    if name == "" { return fmt.Errorf("new app name required") }
    _, err := waveappstore.ValidateAppId(waveappstore.MakeAppId(waveappstore.AppNSLocal, name))
    return err
}

Type guard

func isBareAppName(s string) bool {
    return s != "" && !strings.Contains(s, ":") && strings.TrimSpace(s) == s
}

Try / catch

if err := waveappstore.RenameLocalApp(oldName, newName); err != nil {
    if strings.Contains(err.Error(), "invalid new app name") {
        return fmt.Errorf("choose a different new name: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling RenameLocalApp(oldName, newName) where newName is empty, contains illegal characters, includes a namespace prefix, or otherwise fails ValidateAppId.

Common situations: User-typed new names with spaces or slashes, accidentally passing the full target appId instead of the name, empty newName from an unset variable or empty input field.

Related errors


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