{"record":{"id":"4938f1e52a0d9744","repo":"fatedier/frp","slug":"invalid-argument-visitor-name-is-required","errorCode":null,"errorMessage":"invalid argument: visitor name is required","messagePattern":"invalid argument: visitor name is required","errorType":"http","errorClass":"configmgmt.ErrInvalidArgument","httpStatus":400,"severity":"error","filePath":"client/config_manager.go","lineNumber":263,"sourceCode":"\t}); err != nil {\n\t\treturn err\n\t}\n\n\tlog.Infof(\"store: deleted proxy %q\", name)\n\treturn nil\n}\n\nfunc (m *serviceConfigManager) ListStoreVisitors() ([]v1.VisitorConfigurer, error) {\n\tstoreSource, err := m.storeSourceOrError()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn storeSource.GetAllVisitors()\n}\n\nfunc (m *serviceConfigManager) GetStoreVisitor(name string) (v1.VisitorConfigurer, error) {\n\tif name == \"\" {\n\t\treturn nil, fmt.Errorf(\"%w: visitor name is required\", configmgmt.ErrInvalidArgument)\n\t}\n\n\tstoreSource, err := m.storeSourceOrError()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tcfg := storeSource.GetVisitor(name)\n\tif cfg == nil {\n\t\treturn nil, fmt.Errorf(\"%w: visitor %q\", configmgmt.ErrNotFound, name)\n\t}\n\treturn cfg, nil\n}\n\nfunc (m *serviceConfigManager) CreateStoreVisitor(cfg v1.VisitorConfigurer) (v1.VisitorConfigurer, error) {\n\tif err := m.validateStoreVisitorConfigurer(cfg); err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: validation error: %v\", configmgmt.ErrInvalidArgument, err)\n\t}","sourceCodeStart":245,"sourceCodeEnd":281,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/client/config_manager.go#L245-L281","documentation":"Returned by GetStoreVisitor when the name argument is empty. The visitor store API (GET /api/store/visitors/{name}) requires the visitor's name; an empty identifier fails fast with ErrInvalidArgument before the store source is consulted.","triggerScenarios":"Calling GetStoreVisitor(\"\") directly; a GET request to /api/store/visitors/ where the name segment decodes to empty; URL interpolation with an unset variable.","commonSituations":"Scripts building URLs by concatenation with empty variables; Go code passing a zero-value name field from a partially populated request struct.","solutions":["Pass the exact visitor name: GET /api/store/visitors/my-stcp-visitor.","Fix the empty-variable source (env var, JSON field) upstream.","Discover valid names via GET /api/store/visitors."],"exampleFix":"# before\nname=\"\"\ncurl .../api/store/visitors/$name   # 400 visitor name is required\n\n# after\ncurl .../api/store/visitors/db-visitor","handlingStrategy":"validation","validationCode":"if strings.TrimSpace(name) == \"\" {\n    return errors.New(\"visitor name must be non-empty\")\n}\nvcfg, err := mgr.GetStoreVisitor(name)","typeGuard":null,"tryCatchPattern":"if _, err := mgr.GetStoreVisitor(name); err != nil {\n    if errors.Is(err, configmgmt.ErrInvalidArgument) { /* empty name */ }\n    if errors.Is(err, configmgmt.ErrNotFound) { /* no such visitor */ }\n}","preventionTips":["Name visitors distinctly from proxies (e.g. suffix '-visitor') to avoid passing the wrong identifier","Guard URL builders against empty variables"],"tags":["frp","frpc","store","visitor","validation"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}