siyuan-note/siyuan · error
send article to liandi failed
Error message
send article to liandi failed [sc=%d]
What it means
The kernel POSTs (or PUTs) the exported document to the Liandi article API. If the HTTP response status is not 200, it logs and returns errors.New("send article to liandi failed [sc=<status>]"). The Liandi endpoint accepted the TCP/HTTP exchange but rejected the request at the HTTP status level.
Solutions
- Re-login to Liandi to refresh credentials, then retry the export.
- Inspect the reported status code: 401/403 -> auth, 4xx -> payload problem (try a smaller/simpler document), 5xx -> retry later.
- Check network connectivity and any proxy between the kernel and Liandi.
- Retry after confirming the Liandi service is healthy (the lookup call succeeded earlier).
Defensive patterns
Strategy: retry
Try / catch
if err != nil && strings.Contains(err.Error(), "send article to liandi failed [sc=") {
// parse status code; on 5xx retry with backoff, on 401/403 re-authenticate
} Prevention
- Re-authenticate with Liandi before large or repeated exports
- Keep exported documents within size limits Liandi accepts
- Retry on 5xx only; do not hammer on 4xx
When it happens
Trigger: Calling Export2Liandi and the create/update article call returns a non-200 status: invalid or expired auth token, payload rejected (413/400), server 5xx, or proxy interference.
Common situations: Token expired mid-session; document too large or containing content Liandi rejects; Liandi server outage; network middleware rewriting the response.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- get liandi article info failed
- access to private/internal IP is prohibited
- access to private/internal IP is prohibited
- AI editor request timeout
- AI editor stream idle timeout
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/8801a54fe3b27b2d.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/export.go:508
SetBody(map[string]any{
"articleTitle": title,
"articleTags": tags,
"articleContent": content})
var resp *req.Response
var sendErr error
if foundArticle {
resp, sendErr = request.Put(apiURL)
} else {
resp, sendErr = request.Post(apiURL)
}
if nil != sendErr {
logging.LogErrorf("send article to liandi failed: %s", sendErr)
return sendErr
}
if 200 != resp.StatusCode {
msg := fmt.Sprintf("send article to liandi failed [sc=%d]", resp.StatusCode)
logging.LogError(msg)
return errors.New(msg)
}
if 0 != result.Code {
msg := fmt.Sprintf("send article to liandi failed [code=%d, msg=%s]", result.Code, result.Msg)
logging.LogError(msg)
util.PushClearMsg(msgId)
return errors.New(result.Msg)
}
if !foundArticle {
articleId = result.Data.(string)
tree, _ = LoadTreeByBlockID(id) // 这里必须重新加载,因为前面导出时已经修改了树结构
tree.Root.SetIALAttr(liandiArticleIdAttrName, articleId)
if err = writeTreeUpsertQueue(tree); err != nil {
return err
}
}
View on GitHub (pinned to 9f775e8a12)