wavetermdev/waveterm · error

invalid appId: namespace and name cannot be empty

Error message

invalid appId: namespace and name cannot be empty

What it means

ParseAppId accepts exactly two '/'-separated segments but rejects ids where either the namespace or the name segment is empty. This catches malformed ids like "/myapp" (missing namespace), "local/" (missing name), or "//". The segments become directory names under ~/.waveapps, so empty segments would produce invalid paths.

Source

Thrown at pkg/waveappstore/waveappstore.go:55

type FileData struct {
	Contents []byte
	ModTs    int64
}

func MakeAppId(appNS string, appName string) string {
	return appNS + "/" + appName
}

func ParseAppId(appId string) (appNS string, appName string, err error) {
	parts := strings.Split(appId, "/")
	if len(parts) != 2 {
		return "", "", fmt.Errorf("invalid appId format: must be namespace/name")
	}
	appNS = parts[0]
	appName = parts[1]
	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-]+")
	}

View on GitHub (pinned to a4447c1563)

Solutions

  1. Ensure both segments are non-empty: "local/myapp", not "/myapp" or "local/".
  2. Use waveappstore.MakeAppId(ns, name) with validated ns/name inputs rather than manual concatenation.
  3. Log or validate ns and name separately before combining them into an appId.
  4. Call waveappstore.ValidateAppId to catch this together with length/pattern issues.

Example fix

// before
ns := os.Getenv("WAVE_APP_NS") // "" if unset
appId := ns + "/myapp"          // "/myapp" -> error
// after
ns := os.Getenv("WAVE_APP_NS")
if ns == "" {
    ns = waveappstore.AppNSLocal
}
appId := waveappstore.MakeAppId(ns, "myapp")
Defensive patterns

Strategy: validation

Validate before calling

ns, name, err := waveappstore.ParseAppId(appId)
if err == nil && (ns == "" || name == "") {
    err = fmt.Errorf("namespace and name must be non-empty")
}
if err != nil { /* resolve before calling store APIs */ }

Type guard

func hasBothSegments(appId string) bool {
    parts := strings.Split(appId, "/")
    return len(parts) == 2 && parts[0] != "" && parts[1] != ""
}

Try / catch

if err := waveappstore.ValidateAppId(appId); err != nil {
    if strings.Contains(err.Error(), "cannot be empty") {
        return fmt.Errorf("check that WAVE_APP_NS / app name inputs are set: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Passing an appId whose namespace or name is the empty string: "/myapp", "local/", or "/"; building ids via string concatenation like ns + "/" + name where ns or name is an uninitialized/blank variable.

Common situations: An environment variable or config key holding the namespace is unset, so the id starts with '/'; CLI flag parsing yields an empty app name; template/placeholder substitution left a segment blank.

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/8c493938e5bb2178. Report an issue: GitHub.