{"record":{"id":"01204967a25c1b4e","repo":"fatedier/frp","slug":"apply-config-failed-visitor-q-not-found-in-store","errorCode":null,"errorMessage":"apply config failed: visitor %q not found in store after mutation","messagePattern":"apply config failed: visitor %q not found in store after mutation","errorType":"http","errorClass":"configmgmt.ErrApplyConfig","httpStatus":500,"severity":"error","filePath":"client/config_manager.go","lineNumber":437,"sourceCode":") (v1.VisitorConfigurer, error) {\n\tm.svr.reloadMu.Lock()\n\tdefer m.svr.reloadMu.Unlock()\n\n\tstoreSource := m.svr.storeSource\n\tif storeSource == nil {\n\t\treturn nil, fmt.Errorf(\"%w: store API is disabled\", configmgmt.ErrStoreDisabled)\n\t}\n\n\tif err := fn(storeSource); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := m.svr.reloadConfigFromSourcesLocked(); err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: failed to apply config: %v\", configmgmt.ErrApplyConfig, err)\n\t}\n\n\tpersisted := storeSource.GetVisitor(name)\n\tif persisted == nil {\n\t\treturn nil, fmt.Errorf(\"%w: visitor %q not found in store after mutation\", configmgmt.ErrApplyConfig, name)\n\t}\n\treturn persisted.Clone(), nil\n}\n\nfunc (m *serviceConfigManager) validateStoreProxyConfigurer(cfg v1.ProxyConfigurer) error {\n\tif cfg == nil {\n\t\treturn fmt.Errorf(\"invalid proxy config\")\n\t}\n\truntimeCfg := cfg.Clone()\n\tif runtimeCfg == nil {\n\t\treturn fmt.Errorf(\"invalid proxy config\")\n\t}\n\truntimeCfg.Complete()\n\treturn validation.ValidateProxyConfigurerForClient(runtimeCfg)\n}\n\nfunc (m *serviceConfigManager) validateStoreVisitorConfigurer(cfg v1.VisitorConfigurer) error {\n\tif cfg == nil {","sourceCodeStart":419,"sourceCodeEnd":455,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/client/config_manager.go#L419-L455","documentation":"Internal consistency check in withStoreVisitorMutationAndReload: after mutating and reloading, GetVisitor(name) still returns nil, so it errors with ErrApplyConfig. Means the visitor written moments earlier disappeared from the store — concurrent mutation or a flaky store backend.","triggerScenarios":"Concurrent admin API writes racing on the same visitor; an external process modifying the store file at common.store.path between write and read-back.","commonSituations":"Parallel automation jobs; shared store file across processes; storage corruption.","solutions":["Retry the mutation","Serialize visitor mutations in your tooling","Ensure a single frpc instance owns the store file"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Single writer for visitor mutations","One frpc process per store file"],"tags":["frp","frpc","config-store","race-condition","internal"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}