{"record":{"id":"84ad4b6d6d235477","repo":"siyuan-note/siyuan","slug":"conf-language-249","errorCode":null,"errorMessage":"Conf.Language(249)","messagePattern":"Conf\\.Language\\(249\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/sync.go","lineNumber":641,"sourceCode":"\ts3.Region = strings.TrimSpace(s3.Region)\n\ts3.Timeout = util.NormalizeTimeout(s3.Timeout)\n\ts3.ConcurrentReqs = util.NormalizeConcurrentReqs(s3.ConcurrentReqs, conf.ProviderS3)\n\tif Conf.Sync.Provider == conf.ProviderS3 && (Conf.Sync.S3 == nil ||\n\t\tConf.Sync.S3.Endpoint != s3.Endpoint || Conf.Sync.S3.Bucket != s3.Bucket) {\n\t\tif err = requireCompleteAssetDownloads(); err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\n\tConf.Sync.S3 = s3\n\tConf.Save()\n\trefreshLANSyncManager()\n\treturn\n}\n\nfunc validateSyncS3(s3 *conf.S3) error {\n\tif s3 == nil {\n\t\treturn errors.New(Conf.Language(249))\n\t}\n\tfor _, value := range []string{s3.Endpoint, s3.AccessKey, s3.SecretKey, s3.Bucket, s3.Region} {\n\t\tif strings.TrimSpace(value) == \"\" {\n\t\t\treturn errors.New(Conf.Language(249))\n\t\t}\n\t}\n\trawEndpoint := strings.TrimSpace(s3.Endpoint)\n\trawEndpoint = strings.Replace(rawEndpoint, \"http://http(s)://\", \"https://\", 1)\n\trawEndpoint = strings.Replace(rawEndpoint, \"http(s)://\", \"https://\", 1)\n\tif strings.Contains(rawEndpoint, \"://\") && !strings.HasPrefix(rawEndpoint, \"http://\") && !strings.HasPrefix(rawEndpoint, \"https://\") {\n\t\treturn errors.New(Conf.Language(249))\n\t}\n\tendpoint, err := url.Parse(util.NormalizeEndpoint(rawEndpoint))\n\tif err != nil || endpoint.Hostname() == \"\" || (endpoint.Scheme != \"http\" && endpoint.Scheme != \"https\") {\n\t\treturn errors.New(Conf.Language(249))\n\t}\n\treturn nil\n}","sourceCodeStart":623,"sourceCodeEnd":659,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/sync.go#L623-L659","documentation":"validateSyncS3 checks an S3 sync configuration before use. It returns the localized message for key 249 ('Unable to access data due to configuration error...') when the conf.S3 pointer is nil or when any of Endpoint, AccessKey, SecretKey, Bucket, Region is empty or whitespace-only. All five fields are mandatory for S3 sync to address the bucket.","triggerScenarios":"Calling SetSyncProviderS3 with a nil or partially-filled S3 config; loading a config file where S3 fields were never populated; trimming reveals whitespace-only values; newCloudRepositoryWithAssetSourceLocked validating before a sync/download.","commonSituations":"Fresh install where the user enabled S3 sync but only filled some fields; config migration dropping SecretKey (it is not stored in plaintext exports); environment where Region is optional in some S3 providers but required here.","solutions":["Fill in all of Endpoint, AccessKey, SecretKey, Bucket, and Region in Settings - Sync - S3 and save","Pass a fully populated conf.S3 struct to SetSyncProviderS3 (non-empty, trimmed values)","If your provider has no real region, set Region to a placeholder like \"us-east-1\" — it must be non-empty"],"exampleFix":"// before\nmodel.SetSyncProviderS3(&conf.S3{Endpoint: \"https://s3.example.com\", AccessKey: \"k\", SecretKey: \"s\", Bucket: \"b\"})\n// after\nmodel.SetSyncProviderS3(&conf.S3{Endpoint: \"https://s3.example.com\", AccessKey: \"k\", SecretKey: \"s\", Bucket: \"b\", Region: \"us-east-1\"})","handlingStrategy":"validation","validationCode":"function s3ConfigComplete(s3) {\n  return [s3?.Endpoint, s3?.AccessKey, s3?.SecretKey, s3?.Bucket, s3?.Region]\n    .every(v => typeof v === \"string\" && v.trim() !== \"\");\n}","typeGuard":"func s3ConfigComplete(s3 *conf.S3) bool {\n    if s3 == nil { return false }\n    for _, v := range []string{s3.Endpoint, s3.AccessKey, s3.SecretKey, s3.Bucket, s3.Region} {\n        if strings.TrimSpace(v) == \"\" { return false }\n    }\n    return true\n}","tryCatchPattern":null,"preventionTips":["Never save/apply S3 config with any of the five required fields blank","Trim whitespace from fields before persisting","For providers without regions, store a placeholder like us-east-1","Re-validate config after restoring/migrating workspaces, since fields may be dropped"],"tags":["go","s3","sync","configuration","validation"],"backgroundTag":"missing-required-config-field","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}