{"record":{"id":"bde008e0af189eaf","repo":"fatedier/frp","slug":"failed-to-set-config-source-w-bde008","errorCode":null,"errorMessage":"failed to set config source: %w","messagePattern":"failed to set config source: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/frpc/sub/root.go","lineNumber":140,"sourceCode":"func runClient(cfgFilePath string, unsafeFeatures *security.UnsafeFeatures) error {\n\t// Load configuration\n\tresult, err := config.LoadClientConfigResult(cfgFilePath, strictConfigMode)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif result.IsLegacyFormat {\n\t\tfmt.Printf(\"WARNING: ini format is deprecated and the support will be removed in the future, \" +\n\t\t\t\"please use yaml/json/toml format instead!\\n\")\n\t}\n\n\treturn runClientWithAggregator(result, unsafeFeatures, cfgFilePath)\n}\n\n// runClientWithAggregator runs the client using the internal source aggregator.\nfunc runClientWithAggregator(result *config.ClientConfigLoadResult, unsafeFeatures *security.UnsafeFeatures, cfgFilePath string) error {\n\tconfigSource := source.NewConfigSource()\n\tif err := configSource.ReplaceAll(result.Proxies, result.Visitors); err != nil {\n\t\treturn fmt.Errorf(\"failed to set config source: %w\", err)\n\t}\n\n\tvar storeSource *source.StoreSource\n\n\tif result.Common.Store.IsEnabled() {\n\t\tstorePath := result.Common.Store.Path\n\t\tif storePath != \"\" && cfgFilePath != \"\" && !filepath.IsAbs(storePath) {\n\t\t\tstorePath = filepath.Join(filepath.Dir(cfgFilePath), storePath)\n\t\t}\n\n\t\ts, err := source.NewStoreSource(source.StoreSourceConfig{\n\t\t\tPath: storePath,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to create store source: %w\", err)\n\t\t}\n\t\tstoreSource = s\n\t}","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/cmd/frpc/sub/root.go#L122-L158","documentation":"runClientWithAggregator failed at the same ReplaceAll step as error 131, but for configs loaded from files (ClientConfigLoadResult): the proxies and visitors parsed from config files could not be registered into the config source. The wrapped error identifies the first invalid entry.","triggerScenarios":"A config file whose [[proxies]]/[[visitors]] section has an invalid or duplicate name, an unsupported type string, or fields that survive file parsing but fail source-layer validation.","commonSituations":"Two proxies with the same name in one file or across included files; typo in the proxy type (e.g., 'tcpx'); migration leftovers where legacy keys map to incomplete v1 objects.","solutions":["Read the inner error message; it names the proxy/visitor that failed, so grep the config files for that name.","Check for duplicate name fields across all included config files.","Validate the file with the same rules before startup (see defense snippet).","Fix or remove the offending section and reload."],"exampleFix":"# before (frpc.toml)\n[[proxies]]\nname = \"web\"\ntype = \"tcp\"\n[[proxies]]\nname = \"web\"\ntype = \"http\"\n\n# after\n[[proxies]]\nname = \"web\"\ntype = \"tcp\"\n[[proxies]]\nname = \"web2\"\ntype = \"http\"","handlingStrategy":"validation","validationCode":"// Lint the loaded result before starting the service\nnames := map[string]bool{}\nfor _, p := range result.Proxies {\n    b := p.GetBaseConfig()\n    if names[b.Name] {\n        return fmt.Errorf(\"duplicate proxy name %q\", b.Name)\n    }\n    names[b.Name] = true\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Lint config files for duplicate names in CI","Use one config linter across all environments","Wrap ReplaceAll errors with file context in custom tooling"],"tags":["config","frpc","validation","startup"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}