siyuan-note/siyuan · error
invalid cloud login message
Error message
invalid cloud login message
What it means
Custom UnmarshalJSON error for CloudLogin2faData: the msg field of the cloud 2FA login response is absent, null, or not a string, so the response does not conform to the expected {code,msg} envelope and cannot be deserialized.
Solutions
- Inspect the raw response body for the actual shape
- Retry the login to rule out a transient gateway error
- Verify client and cloud service protocol versions match
- If implementing a mock/server, always include a string msg field
Example fix
// before
{"code":0} // msg missing
// after
{"code":0,"msg":"","token":"..."} Defensive patterns
Strategy: try-catch
Validate before calling
function hasMsgField(v: unknown): v is { code: number; msg: string } {
return typeof v === 'object' && v !== null && typeof (v as any).msg === 'string' && (v as any).msg !== null;
} Type guard
function isString(v: unknown): v is string { return typeof v === 'string'; } Try / catch
try { const resp = await cloudLogin(user, pass); } catch (e) { if (String(e).includes('invalid cloud login message')) { log(e, lastRawBody); showCloudServiceError(); } } Prevention
- Validate the full response schema, not just code
- Treat missing msg as a service-side error and surface it to the user
- Retry transient 5xx/HTML responses before parsing
- Keep mock servers compliant with the real response shape
When it happens
Trigger: Unmarshalling a cloud login response JSON where 'msg' is absent, null, or a non-string value (number, object, array).
Common situations: Cloud backend omitting msg on success responses after a protocol update, or error responses from gateways that only include code without msg.
Related errors
- invalid cloud login code
- block ID must be text
- block operation result must be text, block IDs or null
- invalid cloud login token
- invalid OCR metadata
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/a585c95aec138052.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/apicontract/setting_cloud.go:46
return nil, err
}
if fields["msg"], err = json.Marshal(d.Msg); err != nil {
return nil, err
}
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
}View on GitHub (pinned to 9f775e8a12)