siyuan-note/siyuan · error
invalid user
Error message
invalid user
What it means
errInvalidUser ("invalid user") is returned by getUser when the SiYuan cloud /apis/siyuan/user endpoint answers HTTP 401 Unauthorized for the supplied token — the token definitively does not identify a valid user. Callers detect it via model.IsInvalidUserRefresh(err), and resolveCloudUserRefresh treats it as authoritative: the local user is logged out and the invalidation is broadcast to the UI.
Source
Thrown at kernel/model/cloud_service.go:699
desc = audioRegexp.ReplaceAllString(desc, " 语音 ")
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, errInvalidUserView on GitHub (pinned to 8641553a1f)
Solutions
- Log in again to obtain a fresh token (Settings - Account or the login API); the local session is cleared once this error surfaces.
- Do not retry with the same token — 401 is conclusive and resolveCloudUserRefresh will force a logout.
- Use model.IsInvalidUserRefresh(err) in custom integrations to distinguish auth failure from transient network errors (which yield errRequestUserFailed instead).
- If the account should be valid, verify it still exists and is active on the SiYuan cloud service.
Example fix
// before
user, err := model.RefreshUser() // treat all errors the same
// after
user, err := model.RefreshUser()
if model.IsInvalidUserRefresh(err) {
model.LogoutUser() // token invalid; require fresh login
return
}
if err != nil {
// transient failure: safe to retry later
} Defensive patterns
Strategy: try-catch
Validate before calling
// verify refresh outcome before relying on the user
user, err := model.RefreshUser()
if err != nil && model.IsInvalidUserRefresh(err) { /* force re-login */ } Type guard
func isAuthFatal(err error) bool { return model.IsInvalidUserRefresh(err) } Try / catch
if _, err := model.RefreshUser(); model.IsInvalidUserRefresh(err) {
model.LogoutUser()
// surface login UI; do NOT retry with old token
} Prevention
- Always branch on IsInvalidUserRefresh vs other errors — only the former needs re-login
- Listen for the "setCloudUser" broadcast with a userName to notify users which account expired
- Avoid reusing tokens restored from backups
- Keep accounts active on the SiYuan cloud service
When it happens
Trigger: RefreshUser/getUser called with an expired, revoked, or malformed UserToken; the /user API responding 401; tests (TestResolveCloudUserRefresh) verifying the invalid-user refresh path.
Common situations: Token expiry after long uptime; the same account logging in on another device and invalidating the session; server-side account suspension or deletion; a token restored from an old backup config.
Related errors
- Conf.Language(31)
- Account authentication failed, please login again
- Conf.Language(31) (localized cloud auth failure message)
- localized please-sign-in message (Conf.Language(31))
- result["msg"].(string)
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/2389c85385f40bff.
Report an issue: GitHub.