{"record":{"id":"2056d8e9ed3a995f","repo":"fatedier/frp","slug":"type-s-error","errorCode":null,"errorMessage":"type [%s] error","messagePattern":"type \\[(.+?)\\] error","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/config/legacy/visitor.go","lineNumber":178,"sourceCode":"\t}\n\tif cfg.FallbackTimeoutMs <= 0 {\n\t\tcfg.FallbackTimeoutMs = 1000\n\t}\n\treturn\n}\n\n// Visitor loaded from ini\nfunc NewVisitorConfFromIni(prefix string, name string, section *ini.Section) (VisitorConf, error) {\n\t// section.Key: if key not exists, section will set it with default value.\n\tvisitorType := VisitorType(section.Key(\"type\").String())\n\n\tif visitorType == \"\" {\n\t\treturn nil, fmt.Errorf(\"type shouldn't be empty\")\n\t}\n\n\tconf := DefaultVisitorConf(visitorType)\n\tif conf == nil {\n\t\treturn nil, fmt.Errorf(\"type [%s] error\", visitorType)\n\t}\n\n\tif err := conf.UnmarshalFromIni(prefix, name, section); err != nil {\n\t\treturn nil, fmt.Errorf(\"type [%s] error\", visitorType)\n\t}\n\treturn conf, nil\n}\n","sourceCodeStart":160,"sourceCodeEnd":186,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/pkg/config/legacy/visitor.go#L160-L186","documentation":"After confirming the visitor type is non-empty, NewVisitorConfFromIni calls DefaultVisitorConf; if the type is not one of stcp, sudp, xtcp it returns nil and this 'type [<type>] error' is thrown. Only the secret/p2p visitor families are supported.","triggerScenarios":"A visitor section with type = tcp, type = http, or any value other than stcp/sudp/xtcp. Common when users assume any proxy type can be 'visited'.","commonSituations":"Trying to expose a plain tcp proxy's service via a visitor section; misreading docs and putting the underlying proxy type instead of the visitor type.","solutions":["Change type to stcp, sudp, or xtcp depending on the paired proxy","Ensure the matching proxy on the other side uses the same family (stcp<->stcp, sudp<->sudp, xtcp<->xtcp)","Set the correct serverName/sk fields for the chosen visitor type"],"exampleFix":"# before\n[secret-visitor]\ntype = tcp\n\n# after\n[secret-visitor]\ntype = stcp","handlingStrategy":"type-guard","validationCode":"validVisitors := map[string]bool{\"stcp\":true,\"sudp\":true,\"xtcp\":true}\nif !validVisitors[visitorType] {\n    return fmt.Errorf(\"visitor type %q unsupported; use stcp/sudp/xtcp\", visitorType)\n}","typeGuard":"func isValidVisitorType(t string) bool {\n    switch t {\n    case \"stcp\", \"sudp\", \"xtcp\":\n        return true\n    }\n    return false\n}","tryCatchPattern":"if _, err := legacy.NewVisitorConfFromIni(prefix, name, section); err != nil && strings.HasPrefix(err.Error(), \"type [\") { /* map type to visitor family */ }","preventionTips":["Remember visitors exist only for the secret/p2p families","Pair visitor type with the proxy's type","Keep a cheat-sheet of proxy-vs-visitor type sets"],"tags":["config","visitor","validation","legacy-ini","frpc"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}