siyuan-note/siyuan · error

request user failed

Error message

request user failed

What it means

errRequestUserFailed ("request user failed") is returned by getUser and RefreshUser when the cloud /apis/siyuan/user request fails for reasons other than an invalid token: transport errors (network unreachable, DNS, timeout — retries disabled via SetRetryCount(0)), non-200/non-401 HTTP statuses, a UserTokenExpireTime string that fails integer parsing, or a concurrent login race detected in RefreshUser (Conf.GetUser() changed mid-refresh).

Source

Thrown at kernel/model/cloud_service.go:700

		desc = videoRegexp.ReplaceAllString(desc, " 视频 ")
		desc = fileRegexp.ReplaceAllString(desc, " 文件 ")
		desc = strings.ReplaceAll(desc, "\n\n", "")
		desc = strings.TrimSpace(desc)
		shorthand["shorthandDesc"] = desc

		md := shorthand["shorthandContent"].(string)
		shorthand["shorthandMd"] = md
		tree := parse.Parse("", []byte(md), luteEngine.ParseOptions)
		luteEngine.RenderOptions.ProtyleMarkNetImg = false
		content := luteEngine.ProtylePreview(tree, luteEngine.RenderOptions, luteEngine.ParseOptions)
		shorthand["shorthandContent"] = content
	}
	return
}

var (
	errInvalidUser       = errors.New("invalid user")
	errRequestUserFailed = errors.New("request user failed")
)

func getUser(token string) (*conf.User, error) {
	result := map[string]any{}
	request := httpclient.NewCloudRequest30s().SetRetryCount(0)
	resp, err := request.
		SetSuccessResult(&result).
		SetBody(map[string]string{"token": token}).
		Post(util.GetCloudServer() + "/apis/siyuan/user")
	if err != nil {
		logging.LogErrorf("get community user failed: %s", err)
		return nil, errRequestUserFailed
	}
	if http.StatusOK != resp.StatusCode {
		logging.LogErrorf("get community user failed: %d", resp.StatusCode)
		if http.StatusUnauthorized == resp.StatusCode {
			return nil, errInvalidUser
		}

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Check network connectivity to the configured cloud server (util.GetCloudServer()) and any proxy/firewall settings, then retry — unlike errInvalidUser this error is transient and safe to retry.
  2. Inspect kernel logs ("get community user failed" / "convert token expire time ... failed") to identify whether the cause was transport, HTTP status, or expire-time parsing.
  3. If caused by expire-time parsing, log out and back in to rewrite a clean UserData in conf.json.
  4. If it came from the concurrent-refresh race, simply retry; the latest Conf.GetUser() is returned with this sentinel error and state remains consistent.
  5. Distinguish from auth failure with model.IsInvalidUserRefresh(err) — only that case requires re-login.

Example fix

// before
user, err := model.RefreshUser()
if err != nil { return } // treats transient outage as fatal
// after
user, err := model.RefreshUser()
if err != nil {
    if model.IsInvalidUserRefresh(err) {
        model.LogoutUser(); return
    }
    // transient: retry with backoff
    time.Sleep(retryDelay)
    user, err = model.RefreshUser()
}
Defensive patterns

Strategy: retry

Validate before calling

// check reachability of the cloud server before refreshing the user
conn, err := net.DialTimeout("tcp", hostPort(util.GetCloudServer()), 5*time.Second)
if err != nil { /* offline: defer refresh */ } else { conn.Close() }

Type guard

func isTransientUserErr(err error) bool { return errors.Is(err, model.ErrRequestUserFailedEquivalent) || !model.IsInvalidUserRefresh(err) }

Try / catch

user, err := model.RefreshUser()
if err != nil && !model.IsInvalidUserRefresh(err) {
    // transient: retry with exponential backoff
    for i := 0; i < 3; i++ { time.Sleep(backoff(i)); if user, err = model.RefreshUser(); err == nil { break } }
}

Prevention

When it happens

Trigger: No network / cloud server unreachable during user refresh; cloud returning 5xx; malformed user.UserTokenExpireTime failing strconv.ParseInt (cloud_service.go:421); another goroutine changing Conf.GetUser() between snapshot and commit (cloud_service.go:441).

Common situations: Offline or behind a proxy/firewall blocking siyuan cloud; intermittent DNS failures; corporate networks intercepting TLS; clock/format corruption of the expire-time field in conf.json; concurrent UI actions triggering parallel refreshes.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/08552e9322cd05a9. Report an issue: GitHub.