{"record":{"id":"cd64d016df191e55","repo":"wavetermdev/waveterm","slug":"invalid-appid-format-must-be-namespace-name","errorCode":null,"errorMessage":"invalid appId format: must be namespace/name","messagePattern":"invalid appId format: must be namespace/name","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/waveappstore/waveappstore.go","lineNumber":50,"sourceCode":"\nvar (\n\tnamespaceRegex = regexp.MustCompile(`^@?[a-z0-9-]+$`)\n\tappNameRegex   = regexp.MustCompile(`^[a-zA-Z0-9_-]+$`)\n)\n\ntype FileData struct {\n\tContents []byte\n\tModTs    int64\n}\n\nfunc MakeAppId(appNS string, appName string) string {\n\treturn appNS + \"/\" + appName\n}\n\nfunc ParseAppId(appId string) (appNS string, appName string, err error) {\n\tparts := strings.Split(appId, \"/\")\n\tif len(parts) != 2 {\n\t\treturn \"\", \"\", fmt.Errorf(\"invalid appId format: must be namespace/name\")\n\t}\n\tappNS = parts[0]\n\tappName = parts[1]\n\tif appNS == \"\" || appName == \"\" {\n\t\treturn \"\", \"\", fmt.Errorf(\"invalid appId: namespace and name cannot be empty\")\n\t}\n\treturn appNS, appName, nil\n}\n\nfunc ValidateAppId(appId string) error {\n\tappNS, appName, err := ParseAppId(appId)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif len(appNS) > MaxNamespaceLen {\n\t\treturn fmt.Errorf(\"namespace too long: max %d characters\", MaxNamespaceLen)\n\t}\n\tif len(appName) > MaxAppNameLen {","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/waveappstore/waveappstore.go#L32-L68","documentation":"ParseAppId splits a wave appId string on '/' and requires exactly two non-empty segments: namespace and name. This error is returned when the appId does not contain exactly one slash-separated pair — e.g. zero slashes or more than one. It guards the path layout used on disk (~/.waveapps/<ns>/<name>) and downstream validation.","triggerScenarios":"Passing an appId with no '/' (e.g. \"myapp\"), multiple slashes (e.g. \"@team/sub/app\"), a trailing slash (\"local/app/\"), or an empty string to ParseAppId, ValidateAppId, GetAppDir, PublishDraft, RevertDraft, MakeDraftFromLocal, or buildAndRun.","commonSituations":"Hard-coding just the app name and forgetting the namespace prefix; concatenating a namespaced identifier that itself contains a slash; reading an appId from config/CLI with an accidental trailing slash; confusing MakeAppId(ns, name) output with the name alone.","solutions":["Format the appId as namespace/name with exactly one slash, e.g. \"local/myapp\" or \"@team/myapp\".","Use waveappstore.MakeAppId(ns, name) to construct the id instead of string concatenation.","Call waveappstore.ValidateAppId(appId) before use to get precise feedback.","Trim stray '/' characters from user/config-supplied ids."],"exampleFix":"// before\nappId := \"myapp\"                       // missing namespace\nerr := waveappstore.ValidateAppId(appId) // invalid appId format\n// after\nappId := waveappstore.MakeAppId(\"local\", \"myapp\") // \"local/myapp\"\nerr := waveappstore.ValidateAppId(appId)","handlingStrategy":"validation","validationCode":"func checkAppIdFormat(appId string) error {\n    parts := strings.Split(appId, \"/\")\n    if len(parts) != 2 || parts[0] == \"\" || parts[1] == \"\" {\n        return fmt.Errorf(\"appId must be namespace/name with both parts non-empty\")\n    }\n    return nil\n}\nif err := checkAppIdFormat(appId); err != nil { /* handle before calling the library */ }","typeGuard":"func isValidAppIdShape(appId string) bool {\n    parts := strings.Split(appId, \"/\")\n    return len(parts) == 2 && parts[0] != \"\" && parts[1] != \"\"\n}","tryCatchPattern":"if err := waveappstore.ValidateAppId(appId); err != nil {\n    if strings.Contains(err.Error(), \"invalid appId format\") {\n        fmt.Fprintf(os.Stderr, \"usage: appId must look like 'local/myapp', got %q\\n\", appId)\n        os.Exit(2)\n    }\n    return err\n}","preventionTips":["Always build ids with waveappstore.MakeAppId(ns, name), never raw concatenation.","Trim leading/trailing slashes from user or config input.","Call ValidateAppId early at CLI/config boundaries.","Remember the namespace may carry an '@' prefix but still only one '/' total."],"tags":["go","validation","identifier-format","waveapp"],"backgroundTag":"invalid-identifier-format","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}