{"record":{"id":"c5feca86bebceecf","repo":"fatedier/frp","slug":"s-name-cannot-be-empty","errorCode":null,"errorMessage":"%s name cannot be empty","messagePattern":"(.+?) name cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/config/source/store.go","lineNumber":249,"sourceCode":"\told, exists := entries[name]\n\tif !exists {\n\t\treturn fmt.Errorf(\"%w: %s %q\", ErrNotFound, kind, name)\n\t}\n\n\tentries[name] = value\n\treturn s.persistOrRollbackUnlocked(func() {\n\t\tentries[name] = old\n\t})\n}\n\nfunc removeStoreEntry[T any](\n\ts *StoreSource,\n\tentriesFn func(*StoreSource) map[string]T,\n\tkind string,\n\tname string,\n) error {\n\tif name == \"\" {\n\t\treturn fmt.Errorf(\"%s name cannot be empty\", kind)\n\t}\n\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\n\tentries := entriesFn(s)\n\told, exists := entries[name]\n\tif !exists {\n\t\treturn fmt.Errorf(\"%w: %s %q\", ErrNotFound, kind, name)\n\t}\n\n\tdelete(entries, name)\n\treturn s.persistOrRollbackUnlocked(func() {\n\t\tentries[name] = old\n\t})\n}\n\nfunc (s *StoreSource) AddProxy(proxy v1.ProxyConfigurer) error {","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/pkg/config/source/store.go#L231-L267","documentation":"removeStoreEntry (backing RemoveProxy/RemoveVisitor) was called with an empty name. This is a caller-side programming error caught before any locking or state access: an empty string can never name a stored entry.","triggerScenarios":"store.RemoveProxy(\"\") or store.RemoveVisitor(\"\"), typically because the name came from an unset variable, an empty struct field, or a failed lookup whose error was ignored.","commonSituations":"UI/API handler passing through an empty name from a request; reading Name from a nil-ish or freshly initialized config; ignoring an earlier error that would have produced the name.","solutions":["Fix the caller to pass the real entry name; trace where the empty string originated","Guard call sites: skip or reject empty names before calling Remove","Check that the config object you read the name from was actually populated"],"exampleFix":"// before\nstore.RemoveProxy(req.Name) // req.Name == \"\"\n\n// after\nif req.Name == \"\" {\n    return errors.New(\"name is required\")\n}\nreturn store.RemoveProxy(req.Name)","handlingStrategy":"validation","validationCode":"func removeByName(store *source.StoreSource, kind, name string) error {\n\tname = strings.TrimSpace(name)\n\tif name == \"\" {\n\t\treturn fmt.Errorf(\"%s name is required\", kind)\n\t}\n\treturn store.RemoveProxy(name) // or RemoveVisitor\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate non-empty name at the API/HTTP handler boundary before it reaches the store","Lint call sites of RemoveProxy/RemoveVisitor for literal empty-string arguments","Fail loudly on empty names during development — this error is always a caller bug"],"tags":["validation","caller-error","empty-string","go"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}