wavetermdev/waveterm · error

invalid app name: %w

Error message

invalid app name: %w

What it means

RenameLocalApp validates the OLD app name by constructing a local appId and running ValidateAppId. If that fails, the old name itself is invalid and the rename is aborted with "invalid app name: %w". This ensures the source directory path being renamed is well-formed before touching the filesystem.

Source

Thrown at pkg/waveappstore/waveappstore.go:650

	}

	if _, err := os.Stat(localDir); os.IsNotExist(err) {
		return false, nil
	}

	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

View on GitHub (pinned to a4447c1563)

Solutions

  1. Verify the first argument is a bare app name (no namespace prefix, no illegal characters)
  2. Trim and sanitize the name; reject empty strings before calling
  3. Test the name yourself via ValidateAppId(MakeAppId(AppNSLocal, name)) to see the wrapped cause

Example fix

// before
RenameLocalApp("local:my app", "myapp")
// after
RenameLocalApp("myapp", "myapp2") // bare, valid names only
Defensive patterns

Strategy: validation

Validate before calling

func validAppName(name string) error {
    if name == "" || strings.TrimSpace(name) != name { return fmt.Errorf("bad app name %q", name) }
    _, 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 app name") {
        return fmt.Errorf("%q is not a valid app name: %w", oldName, err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling RenameLocalApp(oldName, newName) where oldName is empty, contains illegal characters (slashes, spaces, special chars), or would produce an appId failing ValidateAppId.

Common situations: Passing a full appId ("local:foo") instead of the bare app name, user-typed names with invalid characters, names copied with trailing whitespace or path separators.

Related errors


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