siyuan-note/siyuan · error

invalid cloud login token

Error message

invalid cloud login token

What it means

When the cloud login response code is 0 (success), UnmarshalJSON additionally requires a non-empty 'token' string field. Missing, null, non-string, or empty-string tokens produce 'invalid cloud login token'.

Solutions

  1. Log the raw response and contact/verify cloud service token issuance
  2. Retry the login request
  3. Check the user's cloud account status (may be unable to receive tokens)
  4. Update the client if the cloud API changed the token field name/location
Defensive patterns

Strategy: try-catch

Validate before calling

function hasToken(v: unknown): v is { code: number; msg: string; token: string } {
  return typeof v === 'object' && v !== null && typeof (v as any).token === 'string' && (v as any).token.length > 0;
}

Type guard

function isNonEmptyString(v: unknown): v is string { return typeof v === 'string' && v.length > 0; }

Try / catch

try { const session = await cloudLogin(user, pass); } catch (e) { if (String(e).includes('invalid cloud login token')) { clearPartialSession(); notifyTokenServiceIssue(); } }

Prevention

When it happens

Trigger: A success (code=0) cloud login response that lacks 'token', has token:null or token:"", or a token that is not a JSON string.

Common situations: Cloud service authenticated the user but failed to issue/return a token, partial outage of the token service, or protocol drift where token moved to another field.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at kernel/apicontract/setting_cloud.go:51

	return json.Marshal(fields)
}

func (d *CloudLogin2faData) UnmarshalJSON(raw []byte) error {
	var fields map[string]json.RawMessage
	if err := json.Unmarshal(raw, &fields); err != nil {
		return err
	}
	code, msg := fields["code"], fields["msg"]
	if len(code) == 0 || bytes.Equal(code, []byte("null")) || json.Unmarshal(code, &d.Code) != nil {
		return errors.New("invalid cloud login code")
	}
	if len(msg) == 0 || bytes.Equal(msg, []byte("null")) || json.Unmarshal(msg, &d.Msg) != nil {
		return errors.New("invalid cloud login message")
	}
	if d.Code == 0 {
		var token string
		if json.Unmarshal(fields["token"], &token) != nil || token == "" {
			return errors.New("invalid cloud login token")
		}
	}
	d.Extra = make(map[string]JSONValue, len(fields)-2)
	for key, raw := range fields {
		if key == "code" || key == "msg" {
			continue
		}
		value, err := EncodedJSONValue(raw)
		if err != nil {
			return err
		}
		d.Extra[key] = value
	}
	return nil
}

type Login2faEnvelope struct {
	Code int                `json:"code"`

View on GitHub (pinned to 9f775e8a12)