siyuan-note/siyuan · error

Conf.Language(249)

Error message

Conf.Language(249)

What it means

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.

Solutions

  1. Fill in all of Endpoint, AccessKey, SecretKey, Bucket, and Region in Settings - Sync - S3 and save
  2. Pass a fully populated conf.S3 struct to SetSyncProviderS3 (non-empty, trimmed values)
  3. If your provider has no real region, set Region to a placeholder like "us-east-1" — it must be non-empty

Example fix

// before
model.SetSyncProviderS3(&conf.S3{Endpoint: "https://s3.example.com", AccessKey: "k", SecretKey: "s", Bucket: "b"})
// after
model.SetSyncProviderS3(&conf.S3{Endpoint: "https://s3.example.com", AccessKey: "k", SecretKey: "s", Bucket: "b", Region: "us-east-1"})
Defensive patterns

Strategy: validation

Validate before calling

function s3ConfigComplete(s3) {
  return [s3?.Endpoint, s3?.AccessKey, s3?.SecretKey, s3?.Bucket, s3?.Region]
    .every(v => typeof v === "string" && v.trim() !== "");
}

Type guard

func s3ConfigComplete(s3 *conf.S3) bool {
    if s3 == nil { return false }
    for _, v := range []string{s3.Endpoint, s3.AccessKey, s3.SecretKey, s3.Bucket, s3.Region} {
        if strings.TrimSpace(v) == "" { return false }
    }
    return true
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/84ad4b6d6d235477. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/sync.go:641

	s3.Region = strings.TrimSpace(s3.Region)
	s3.Timeout = util.NormalizeTimeout(s3.Timeout)
	s3.ConcurrentReqs = util.NormalizeConcurrentReqs(s3.ConcurrentReqs, conf.ProviderS3)
	if Conf.Sync.Provider == conf.ProviderS3 && (Conf.Sync.S3 == nil ||
		Conf.Sync.S3.Endpoint != s3.Endpoint || Conf.Sync.S3.Bucket != s3.Bucket) {
		if err = requireCompleteAssetDownloads(); err != nil {
			return
		}
	}

	Conf.Sync.S3 = s3
	Conf.Save()
	refreshLANSyncManager()
	return
}

func validateSyncS3(s3 *conf.S3) error {
	if s3 == nil {
		return errors.New(Conf.Language(249))
	}
	for _, value := range []string{s3.Endpoint, s3.AccessKey, s3.SecretKey, s3.Bucket, s3.Region} {
		if strings.TrimSpace(value) == "" {
			return errors.New(Conf.Language(249))
		}
	}
	rawEndpoint := strings.TrimSpace(s3.Endpoint)
	rawEndpoint = strings.Replace(rawEndpoint, "http://http(s)://", "https://", 1)
	rawEndpoint = strings.Replace(rawEndpoint, "http(s)://", "https://", 1)
	if strings.Contains(rawEndpoint, "://") && !strings.HasPrefix(rawEndpoint, "http://") && !strings.HasPrefix(rawEndpoint, "https://") {
		return errors.New(Conf.Language(249))
	}
	endpoint, err := url.Parse(util.NormalizeEndpoint(rawEndpoint))
	if err != nil || endpoint.Hostname() == "" || (endpoint.Scheme != "http" && endpoint.Scheme != "https") {
		return errors.New(Conf.Language(249))
	}
	return nil
}

View on GitHub (pinned to 9f775e8a12)