wavetermdev/waveterm · error
invalid app name: must match pattern [a-zA-Z0-9_-]+
Error message
invalid app name: must match pattern [a-zA-Z0-9_-]+
What it means
The app name segment of an appId must match ^[a-zA-Z0-9_-]+$ — only ASCII letters, digits, underscores, and hyphens. This error means the name contains other characters (dots, spaces, slashes, unicode) making it unsafe as a directory name under ~/.waveapps.
Source
Thrown at pkg/waveappstore/waveappstore.go:75
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) {
return fmt.Errorf("failed to remove existing directory: %w", err)
}
if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {View on GitHub (pinned to a4447c1563)
Solutions
- Sanitize the name: replace '.' and spaces with '-' or '_', and transliterate/strip non-ASCII characters.
- Use a slug function before composing the appId (e.g. strings.NewReplacer(".", "-", " ", "-")).
- Pre-validate in UI with pattern ^[a-zA-Z0-9_-]+$ and reject at input time.
- Use "myapp-1-0" style version suffixes instead of dotted versions.
Example fix
// before appId := "local/myapp-1.0" // dot not allowed in app name err := waveappstore.ValidateAppId(appId) // after appId := "local/myapp-1-0" // matches ^[a-zA-Z0-9_-]+$ err := waveappstore.ValidateAppId(appId)
Defensive patterns
Strategy: validation
Validate before calling
var appNamePattern = regexp.MustCompile(`^[a-zA-Z0-9_-]+$`)
func namePatternOK(appId string) bool {
_, name, err := waveappstore.ParseAppId(appId)
return err == nil && appNamePattern.MatchString(name)
} Type guard
func isValidAppName(name string) bool {
return regexp.MustCompile(`^[a-zA-Z0-9_-]+$`).MatchString(name)
} Try / catch
if err := waveappstore.ValidateAppId(appId); err != nil {
if strings.Contains(err.Error(), "invalid app name") {
return fmt.Errorf("app name may only contain letters, digits, '_' and '-': %w", err)
}
return err
} Prevention
- Sanitize derived names: replace dots/spaces with '-' and strip non-ASCII.
- Use hyphen version suffixes ('myapp-1-0'), not dotted ones.
- Validate the name pattern in UI forms before publishing or writing files.
- Test app names copied from file names and titles — the most common source of bad characters.
When it happens
Trigger: Calling ValidateAppId (directly or via GetAppDir, PublishDraft, RevertDraft, MakeDraftFromLocal, DeleteApp, WriteAppFile) with app names like "my.app", "my app", "マイアプリ", or "app v2" after the namespace slash.
Common situations: Deriving app names from file names or titles that include dots and spaces; localized/unicode app titles used verbatim as ids; version suffixes like "myapp-1.0" containing a dot.
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
- invalid namespace: must match pattern @?[a-z0-9-]+
- invalid AIMessage: %w
- part %d: text type requires non-empty text field
- invalid format of user@host argument
- file info is required
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/742855864d8d6963.
Report an issue: GitHub.