{"record":{"id":"5ccc13eb28dbf488","repo":"siyuan-note/siyuan","slug":"invalid-provider-d","errorCode":null,"errorMessage":"invalid provider [%d]","messagePattern":"invalid provider \\[(.+?)\\]","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/repository.go","lineNumber":3001,"sourceCode":"\t\t\tConcurrentReqs: Conf.Sync.S3.ConcurrentReqs,\n\t\t}\n\tcase conf.ProviderWebDAV:\n\t\tret.WebDAV = &cloud.ConfWebDAV{\n\t\t\tEndpoint:       Conf.Sync.WebDAV.Endpoint,\n\t\t\tUsername:       Conf.Sync.WebDAV.Username,\n\t\t\tPassword:       Conf.Sync.WebDAV.Password,\n\t\t\tSkipTlsVerify:  Conf.Sync.WebDAV.SkipTlsVerify,\n\t\t\tTimeout:        Conf.Sync.WebDAV.Timeout,\n\t\t\tConcurrentReqs: Conf.Sync.WebDAV.ConcurrentReqs,\n\t\t}\n\tcase conf.ProviderLocal:\n\t\tret.Local = &cloud.ConfLocal{\n\t\t\tEndpoint:       Conf.Sync.Local.Endpoint,\n\t\t\tTimeout:        Conf.Sync.Local.Timeout,\n\t\t\tConcurrentReqs: Conf.Sync.Local.ConcurrentReqs,\n\t\t}\n\tdefault:\n\t\terr = fmt.Errorf(\"invalid provider [%d]\", Conf.Sync.Provider)\n\t\treturn\n\t}\n\treturn\n}\n\ntype Backup struct {\n\tSize    int64  `json:\"size\"`\n\tHSize   string `json:\"hSize\"`\n\tUpdated string `json:\"updated\"`\n\tSaveDir string `json:\"saveDir\"` // 本地备份数据存放目录路径\n}\n\ntype Sync struct {\n\tSize      int64  `json:\"size\"`\n\tHSize     string `json:\"hSize\"`\n\tUpdated   string `json:\"updated\"`\n\tCloudName string `json:\"cloudName\"` // 云端同步数据存放目录名\n\tSaveDir   string `json:\"saveDir\"`   // 本地同步数据存放目录路径","sourceCodeStart":2983,"sourceCodeEnd":3019,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/afa823b6b4e4f183511e0bc0a3be93caa94c7c97/kernel/model/repository.go#L2983-L3019","documentation":"buildCloudConf() assembles the provider-specific cloud configuration from the same switch; an out-of-range Conf.Sync.Provider reaches the default branch and returns fmt.Errorf(\"invalid provider [%d]\", ...). It fails earlier than newRepository's client construction, so most sync paths surface this message first when the provider value is bad.","triggerScenarios":"Any call that needs cloud credentials — newSyncRepository, GetCloudSpace, backup/sync setup — while Conf.Sync.Provider is not 0/2/3/4 (kernel/model/repository.go:3001). Typically the same corrupted conf.json as the sibling 'unknown cloud provider' error.","commonSituations":"Hand-edited or migrated conf.json; a fork or plugin writing an unsupported provider id; downgrade to a version that dropped a legacy provider.","solutions":["Re-select the provider in Settings - Account & Sync so the kernel rewrites a valid provider id","Fix workspace/conf.json manually: set sync.provider to 0 (SiYuan), 2 (S3), 3 (WebDAV), or 4 (local) and restart","Check for plugins/tools that mutate sync settings and remove or update them"],"exampleFix":"// before\nif err := model.SyncData(true); err != nil { /* invalid provider [7] */ }\n\n// after: normalize before use\nif p := model.Conf.Sync.Provider; p != 0 && p != 2 && p != 3 && p != 4 {\n    model.Conf.Sync.Provider = 0 // default to official cloud, then reconfigure in UI\n}\nerr := model.SyncData(true)","handlingStrategy":"validation","validationCode":"switch model.Conf.Sync.Provider {\ncase 0, 2, 3, 4:\n    // ok\ndefault:\n    return errors.New(\"invalid sync provider; fix conf.json or re-select in Settings\")\n}\n_, err := model.GetCloudSpace()","typeGuard":"func isValidSyncProvider(p int) bool {\n    return p >= 0 && p <= 4 && p != 1 // 1 is a removed legacy id\n}","tryCatchPattern":null,"preventionTips":["Keep provider ids centralized (kernel/conf/sync.go constants) when writing tools that touch sync config","Validate config after migrations between versions","Prefer the settings API over direct conf.json writes"],"tags":["config","sync","provider","enum","siyuan"],"backgroundTag":"invalid-config-enum-value","analyzedSha":"afa823b6b4e4f183511e0bc0a3be93caa94c7c97","analyzedAt":"2026-08-18T17:04:10.865Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}