{"record":{"id":"bb889d6f67d61edb","repo":"fatedier/frp","slug":"name-is-required","errorCode":null,"errorMessage":"name is required","messagePattern":"name is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/config/v1/validation/visitor.go","lineNumber":44,"sourceCode":"\tbase := c.GetBaseConfig()\n\tif err := validateVisitorBaseConfig(base); err != nil {\n\t\treturn err\n\t}\n\n\tswitch v := c.(type) {\n\tcase *v1.STCPVisitorConfig:\n\tcase *v1.SUDPVisitorConfig:\n\tcase *v1.XTCPVisitorConfig:\n\t\treturn validateXTCPVisitorConfig(v)\n\tdefault:\n\t\treturn errors.New(\"unknown visitor config type\")\n\t}\n\treturn nil\n}\n\nfunc validateVisitorBaseConfig(c *v1.VisitorBaseConfig) error {\n\tif c.Name == \"\" {\n\t\treturn errors.New(\"name is required\")\n\t}\n\n\tif c.ServerName == \"\" {\n\t\treturn errors.New(\"server name is required\")\n\t}\n\n\tif c.BindPort == 0 {\n\t\treturn errors.New(\"bind port is required\")\n\t}\n\treturn nil\n}\n\nfunc validateXTCPVisitorConfig(c *v1.XTCPVisitorConfig) error {\n\tif !slices.Contains([]string{\"kcp\", \"quic\"}, c.Protocol) {\n\t\treturn fmt.Errorf(\"protocol should be kcp or quic\")\n\t}\n\treturn nil\n}","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/pkg/config/v1/validation/visitor.go#L26-L62","documentation":"Validation error from validateVisitorBaseConfig: a [[visitors]] entry in the frpc config has an empty name. The visitor name identifies it locally in frpc (and pairs it with the client-side config), so it is mandatory. This is the first check in the visitor base validation, run by ValidateVisitorConfigurer for every visitor type.","triggerScenarios":"A [[visitors]] entry whose name key is missing or set to \"\" — e.g. a copied visitor template where name was deleted, or TOML keys misplaced so the entry decodes to zero values.","commonSituations":"Writing the first stcp/xtcp visitor and forgetting that visitors need their own name distinct from serverName; key typo like Name or visitor; programmatic visitor construction without VisitorBaseConfig.Name.","solutions":["Add name = \"my-visitor\" to the [[visitors]] entry.","Keep the name distinct from serverName: name identifies the local visitor, serverName identifies the remote proxy being visited.","If generating configs in Go, set VisitorBaseConfig.Name before validation."],"exampleFix":"# before\n[[visitors]]\ntype = \"stcp\"\nserverName = \"stcp-srv\"\nsecretKey = \"s\"\nbindAddr = \"127.0.0.1\"\nbindPort = 9000\n\n# after\n[[visitors]]\nname = \"stcp-visitor\"\ntype = \"stcp\"\nserverName = \"stcp-srv\"\nsecretKey = \"s\"\nbindAddr = \"127.0.0.1\"\nbindPort = 9000","handlingStrategy":"validation","validationCode":"for _, v := range clientCfg.Visitors {\n    if v.GetBaseConfig() == nil || v.GetBaseConfig().Name == \"\" {\n        return errors.New(\"every visitor needs a non-empty name\")\n    }\n}","typeGuard":"func visitorNameSet(c v1.VisitorConfigurer) bool {\n    base := c.GetBaseConfig()\n    return c != nil && base != nil && base.Name != \"\"\n}","tryCatchPattern":"if err := validation.ValidateVisitorConfigurer(v); err != nil {\n    if strings.Contains(err.Error(), \"name is required\") {\n        // add name = \"my-visitor\" to the [[visitors]] entry\n    }\n    return err\n}","preventionTips":["Start every visitor template with name, type, serverName, bindPort.","Keep visitor name distinct from serverName.","Run frpc verify on config changes."],"tags":["config","visitor","validation","frpc","naming"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}