siyuan-note/siyuan · error

Conf.Language(77), msg: get endpoint

Error message

Conf.Language(77), msg: get endpoint [%s] abs path failed

What it means

SetSyncProviderLocal converts the configured local sync folder to an absolute path with filepath.Abs; if that fails it logs "get endpoint [%s] abs path failed" and wraps the log message in Conf.Language(77), the generic "sync config failed" user-facing error. filepath.Abs essentially only fails when Getwd fails (relative path with an unusable working directory), so this is a rare environment-level failure.

Solutions

  1. Restart the kernel from a valid working directory so Getwd succeeds
  2. Pass an absolute path (e.g. /home/user/siyuan-sync) as the local endpoint instead of a relative one
  3. Check that the process's cwd exists and is readable (ls -d /proc/<pid>/cwd on Linux)
  4. Ensure the endpoint points to an existing directory — the very next check also rejects non-existent paths with the same Language(77) error

Example fix

// before
local.Endpoint = "siyuan-sync"  // relative path, cwd unusable
// after
local.Endpoint = "/home/user/siyuan-sync"
Defensive patterns

Strategy: validation

Validate before calling

if !filepath.IsAbs(endpoint) {
	abs, err := filepath.Abs(endpoint)
	if err != nil {
		return fmt.Errorf("cannot resolve endpoint %q to an absolute path: %v", endpoint, err)
	}
	endpoint = abs
}
if !gulu.File.IsExist(endpoint) {
	return fmt.Errorf("endpoint %q does not exist", endpoint)
}

Try / catch

if err := model.SetSyncProviderLocal(cfg); err != nil {
	log.Printf("local sync provider rejected: %v", err)
	// fall back to a verified absolute, existing directory path
}

Prevention

When it happens

Trigger: Calling SetSyncProviderLocal (via the setSyncProviderLocalContract API) with a relative endpoint path while the kernel process's current working directory cannot be resolved (Getwd error, e.g. cwd deleted or permission-restricted), making filepath.Abs fail.

Common situations: Kernel launched from a directory that was removed or is no longer accessible; running the kernel as a service with a broken cwd; sandboxed/containerized environments restricting Getwd; endpoint supplied as a bare relative folder name instead of an absolute path in such an environment.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at kernel/model/sync.go:700

	}

	Conf.Sync.WebDAV = webdav
	Conf.Save()
	refreshLANSyncManager()
	return
}

func SetSyncProviderLocal(local *conf.Local) (err error) {
	release := lockAssetSourceChange()
	defer release()
	local.Endpoint = strings.TrimSpace(local.Endpoint)
	local.Endpoint = util.NormalizeLocalPath(local.Endpoint)

	absPath, err := filepath.Abs(local.Endpoint)
	if nil != err {
		msg := fmt.Sprintf("get endpoint [%s] abs path failed: %s", local.Endpoint, err)
		logging.LogError(msg)
		err = fmt.Errorf(Conf.Language(77), msg)
		return
	}
	if !gulu.File.IsExist(absPath) {
		msg := fmt.Sprintf("endpoint [%s] not exist", local.Endpoint)
		logging.LogError(msg)
		err = fmt.Errorf(Conf.Language(77), msg)
		return
	}
	if util.IsAbsPathInWorkspace(absPath) || filepath.Clean(absPath) == filepath.Clean(util.WorkspaceDir) {
		msg := fmt.Sprintf("endpoint [%s] is in workspace", local.Endpoint)
		logging.LogError(msg)
		err = fmt.Errorf(Conf.Language(77), msg)
		return
	}

	if gulu.File.IsSubPath(absPath, util.WorkspaceDir) {
		msg := fmt.Sprintf("endpoint [%s] is parent of workspace", local.Endpoint)
		logging.LogError(msg)

View on GitHub (pinned to 9f775e8a12)