wavetermdev/waveterm · error

invalid namespace: must match pattern @?[a-z0-9-]+

Error message

invalid namespace: must match pattern @?[a-z0-9-]+

What it means

The namespace segment of an appId must match ^@?[a-z0-9-]+$ — optionally starting with '@', then only lowercase letters, digits, and hyphens. This error means the namespace contains other characters (uppercase, underscores, dots, spaces, slashes) or is otherwise malformed.

Source

Thrown at pkg/waveappstore/waveappstore.go:72

	if appNS == "" || appName == "" {
		return "", "", fmt.Errorf("invalid appId: namespace and name cannot be empty")
	}
	return appNS, appName, nil
}

func ValidateAppId(appId string) error {
	appNS, appName, err := ParseAppId(appId)
	if err != nil {
		return err
	}
	if len(appNS) > MaxNamespaceLen {
		return fmt.Errorf("namespace too long: max %d characters", MaxNamespaceLen)
	}
	if len(appName) > MaxAppNameLen {
		return fmt.Errorf("app name too long: max %d characters", MaxAppNameLen)
	}
	if !namespaceRegex.MatchString(appNS) {
		return fmt.Errorf("invalid namespace: must match pattern @?[a-z0-9-]+")
	}
	if !appNameRegex.MatchString(appName) {
		return fmt.Errorf("invalid app name: must match pattern [a-zA-Z0-9_-]+")
	}
	return nil
}

func GetAppDir(appId string) (string, error) {
	if err := ValidateAppId(appId); err != nil {
		return "", err
	}
	appNS, appName, _ := ParseAppId(appId)
	homeDir := wavebase.GetHomeDir()
	return filepath.Join(homeDir, "waveapps", appNS, appName), nil
}

func copyDir(src, dst string) error {
	if err := os.RemoveAll(dst); err != nil && !os.IsNotExist(err) {

View on GitHub (pinned to a4447c1563)

Solutions

  1. Normalize the namespace to lowercase and replace '_'/'.' and other characters with '-'.
  2. Keep the optional '@' prefix only at position 0 (reserved for team/organization namespaces).
  3. Pre-validate in UI with the pattern ^@?[a-z0-9-]+$ and show a clear message.
  4. Migrate any existing app directories stored under non-conforming namespaces to compliant names.

Example fix

// before
appId := "@MyOrg_App/myapp" // uppercase and underscore -> invalid namespace
err := waveappstore.ValidateAppId(appId)
// after
appId := "@myorg-app/myapp" // matches ^@?[a-z0-9-]+$
err := waveappstore.ValidateAppId(appId)
Defensive patterns

Strategy: validation

Validate before calling

var namespacePattern = regexp.MustCompile(`^@?[a-z0-9-]+$`)
func nsPatternOK(appId string) bool {
    ns, _, err := waveappstore.ParseAppId(appId)
    return err == nil && namespacePattern.MatchString(ns)
}

Type guard

func isValidNamespace(ns string) bool {
    return regexp.MustCompile(`^@?[a-z0-9-]+$`).MatchString(ns)
}

Try / catch

if err := waveappstore.ValidateAppId(appId); err != nil {
    if strings.Contains(err.Error(), "invalid namespace") {
        return fmt.Errorf("namespace may only contain lowercase letters, digits, and hyphens (optional leading '@'): %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling ValidateAppId (directly or via GetAppDir, PublishDraft, RevertDraft, MakeDraftFromLocal, DeleteApp, WriteAppFile) with namespaces like "MyOrg/app", "my_org/app", "my.org/app", "@Team/app", or "my org/app".

Common situations: Using a GitHub org, npm scope, or domain as the namespace without normalizing case/punctuation ('@MyOrg', 'example.com'); users typing underscores where hyphens are required; copy-pasting ids with spaces or uppercase.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


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