siyuan-note/siyuan · error

requestResult.Msg

Error message

requestResult.Msg

What it means

In CloudChatGPT, when the cloud server responds with a non-zero requestResult.Code, the server's requestResult.Msg string is wrapped in errors.New and returned with stop=true. This is a pass-through of a business-logic error from the cloud AI endpoint (e.g. quota exhausted, model unavailable, content policy).

Source

Thrown at kernel/model/cloud_service.go:74

		"role":    "user",
		"content": msg,
	})
	payload["messages"] = messages

	requestResult := gulu.Ret.NewResult()
	request := httpclient.NewCloudRequest30s()
	_, err = request.
		SetSuccessResult(requestResult).
		SetCookies(&http.Cookie{Name: "symphony", Value: Conf.GetUser().UserToken}).
		SetBody(payload).
		Post(util.GetCloudServer() + "/apis/siyuan/ai/chatGPT")
	if err != nil {
		logging.LogErrorf("chat gpt failed: %s", err)
		err = ErrFailedToConnectCloudServer
		return
	}
	if 0 != requestResult.Code {
		err = errors.New(requestResult.Msg)
		stop = true
		return
	}

	data := requestResult.Data.(map[string]any)
	choices := data["choices"].([]any)
	if 1 > len(choices) {
		stop = true
		return
	}
	choice := choices[0].(map[string]any)
	message := choice["message"].(map[string]any)
	ret = message["content"].(string)

	if nil != choice["finish_reason"] {
		finishReason := choice["finish_reason"].(string)
		if "length" == finishReason {
			stop = false

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Display requestResult.Msg to the user as it carries the authoritative reason.
  2. If the message indicates quota/plan limits, guide the user to upgrade or wait for quota reset.
  3. Retry on transient server errors, but not on quota/policy codes.
  4. Confirm the user is signed in and has an active subscription before retrying.

Example fix

// before
ret, stop, err := CloudChatGPT(msg, ctx)
if err != nil { log.Println(err) }

// after
ret, stop, err := CloudChatGPT(msg, ctx)
if err != nil {
    if errors.Is(err, model.ErrFailedToConnectCloudServer) {
        // network issue
    } else {
        showUser(err.Error()) // server-provided Msg
    }
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check subscription before calling the AI endpoint
if Conf.GetUser() == nil || !Conf.GetUser().IsAIEnabled() { return errors.New("AI not available for this account") }

Type guard

func isServerBusinessError(err error) bool {
    return err != nil && !errors.Is(err, model.ErrFailedToConnectCloudServer) && !isAuthError(err)
}

Try / catch

_, _, err := model.CloudChatGPT(msg, ctx)
if err != nil {
    if errors.Is(err, model.ErrFailedToConnectCloudServer) { handleNetwork() }
    else if isAuthError(err) { routeToLogin() }
    else { showUser(err.Error()) /* server Msg, do not retry quota/policy errors */ }
}

Prevention

When it happens

Trigger: The POST to /apis/siyuan/ai/chatGPT succeeds at the HTTP layer (no transport error, not a 401) but the JSON result envelope carries Code != 0. The Msg field holds the human-readable reason from the server.

Common situations: AI subscription quota used up; the user's plan does not include AI access; the cloud rejected the prompt on content policy; transient server-side AI provider outage surfaced as a non-zero code.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/cb39b4a327947d23. Report an issue: GitHub.