Troubleshooting Publishing Issues in xiaohongshu-mcp: A Complete Guide
The most common publishing failures in xiaohongshu-mcp stem from DOM blocking elements, navigation tab switching errors, and upload timeouts, which can be diagnosed by checking the mustClickPublishTab, removePopCover, and waitForUploadComplete functions in the source code.
When automating content publication to 小红书 (Xiaohongshu) using the xpzouying/xiaohongshu-mcp repository, failures typically occur within the browser automation layer built on go-rod. Understanding the specific failure points in xiaohongshu/publish.go and xiaohongshu/publish_video.go allows you to implement effective troubleshooting publishing issues in xiaohongshu-mcp workflows.
Common Publishing Failure Points
Navigation and Tab Switching Errors
The publishing flow begins by navigating to the creator studio and switching to the appropriate upload tab. When NewPublishImageAction or NewPublishVideoAction initializes, it calls mustClickPublishTab (publish.go L59-L62).
If you encounter errors like "未找到发布 TAB" (publish tab not found) or "切换到上传图文失败" (failed to switch to image upload), verify that:
- The browser page has fully loaded the creator studio URL
- The DOM selectors for the publish tab haven't changed in the Xiaohongshu UI
- No network interception is blocking the creator studio JavaScript
DOM Blocking and Element Visibility
Xiaohongshu's interface frequently displays pop-ups, notifications, or cookie banners that block interaction with underlying elements. The code attempts to handle this via removePopCover and isElementBlocked (publish.go L35-L41).
Symptoms include:
- "发布 TAB 被遮挡" (publish tab is blocked)
- Click events that return success but trigger no UI change
- Timeouts waiting for element visibility
To resolve these issues, manually inspect the page for div.d-popover elements or modal overlays. The automation expects a clean DOM state before proceeding with mustClickPublishTab.
Image and Video Upload Timeouts
File upload operations are asynchronous and depend on Xiaohongshu's CDN processing. The image upload flow uses uploadImages which calls waitForUploadComplete (publish.go L43-L71), while video publishing uses uploadVideo (publish_video.go L73-L90).
Common upload failures include:
- "图片上传超时" (image upload timeout)
- "未找到视频上传输入框" (video upload input not found)
- Preview images that never appear in the UI
The code waits for the selector .img-preview-area .pr to match the expected image count. If Xiaohongshu updates their CSS classes, this selector will fail and require updating in waitForUploadComplete.
Content Validation Errors
Before submission, the code validates title and content length constraints via checkTitleMaxLength and checkContentMaxLength (publish.go L64-L84).
Errors you may encounter:
- "标题超过最大长度" (title exceeds maximum length)
- "正文超过最大长度" (content exceeds maximum length)
These validations mirror the UI constraints found in div.title-container div.max_suffix and div.edit-container div.length-error. Ensure your content respects these limits before calling the publish action.
Schedule and Visibility Configuration
Advanced publishing options include scheduling and visibility settings, handled by setSchedulePublish and setVisibility (publish.go L47-L55).
Troubleshooting tips:
- Use exact Chinese strings for visibility:
公开可见,仅自己可见, or仅互关好友可见 - Schedule times must be in RFC3339 format and in the future
- If the scheduled post never appears, verify the system clock and timezone settings
Product Binding and Original Declaration
E-commerce features and copyright declarations add complexity via bindProducts (publish.go L45-L53) and setOriginal with confirmOriginalDeclaration (publish.go L98-L108).
Common issues:
- "绑定商品失败" (product binding failed) when the "添加商品" button is not found
- "原创声明弹窗卡死" (original declaration popup freeze) when the confirmation checklist selector fails
Ensure the product search workflow in searchAndSelectProduct can locate your items, and verify that the original declaration popup DOM structure matches the selectors in confirmOriginalDeclaration.
Step-by-Step Debugging Checklist
Follow this systematic approach to isolate publishing failures:
-
Verify Login State – Ensure the browser session is authenticated using
LoginAction.CheckLoginStatus. If unauthenticated, fetch the QR code viaFetchQrcodeImageand wait for login completion withWaitForLogin. -
Confirm Navigation – Manually open
https://creator.xiaohongshu.com/publish/publish?source=officialand verify the "上传图文" or "上传视频" tab is present and clickable. -
Inspect DOM Blocking – Check for floating pop-overs (
div.d-popover) or modal overlays. TheremovePopCoverfunction attempts to delete these automatically, but manual intervention may be required if selectors change. -
Validate File Paths – Run
os.Statchecks on image and video paths. Missing files cause early returns before upload begins. -
Monitor Upload Progress – Watch console logs for "图片已提交上传" messages and preview counts in
waitForUploadComplete. If the.img-preview-area .prselector fails to match expected counts, update the selector in the source. -
Check Content Constraints – Verify title and content lengths respect UI limits displayed in
div.max_suffixanddiv.length-errorelements to avoidmakeMaxLengthErrorreturns. -
Validate Schedule and Visibility – Use exact Chinese visibility strings (
公开可见,仅自己可见,仅互关好友可见) and RFC3339 formatted schedule times. -
Handle Popups and Declarations – For original declarations, ensure the popup DOM structure matches
confirmOriginalDeclarationselectors. For product binding, verifyclickAddProductButtoncan locate the add product button. -
Analyze Error Traces – When errors occur, inspect the wrapped stack trace produced by
github.com/pkg/errorsto identify the exact function and line number causing the failure.
Code Examples for Error Handling
The following examples demonstrate robust error handling patterns when troubleshooting publishing issues in xiaohongshu-mcp.
Retry Logic for Image Publishing
package main
import (
"context"
"fmt"
"time"
"github.com/go-rod/rod"
"xiao/hongshu/v2/xiaohongshu"
)
func main() {
browser := rod.New().MustConnect()
defer browser.Close()
page := browser.MustPage()
defer page.Close()
// Ensure login first (omitted for brevity)
//
action, err := xiaohongshu.NewPublishImageAction(page)
if err != nil {
panic(fmt.Sprintf("create action failed: %v", err))
}
content := xiaohongshu.PublishImageContent{
Title: "我的第一篇笔记",
Content: "这是使用 xiaohongshu‑mcp 自动发布的内容",
ImagePaths: []string{"/tmp/pic1.jpg", "/tmp/pic2.jpg"},
Tags: []string{"#自动化", "#go"},
Visibility: "公开可见",
}
// Simple retry loop
for i := 0; i < 3; i++ {
if err := action.Publish(context.Background(), content); err != nil {
fmt.Printf("publish attempt %d failed: %v\n", i+1, err)
time.Sleep(2 * time.Second)
continue
}
fmt.Println("publish succeeded")
break
}
}
HTTP API Error Handling
package main
import (
"bytes"
"encoding/json"
"net/http"
"time"
)
type VideoReq struct {
Title string `json:"title"`
Content string `json:"content"`
Video string `json:"video"` // absolute local path
Tags []string `json:"tags,omitempty"`
Visibility string `json:"visibility,omitempty"`
ScheduleTime string `json:"schedule_time,omitempty"` // RFC3339, optional
Products []string `json:"products,omitempty"`
}
func main() {
req := VideoReq{
Title: "演示视频",
Content: "使用 MCP 发布的演示视频",
Video: "/Users/me/Videos/demo.mp4",
Tags: []string{"#demo"},
Visibility: "仅自己可见",
}
body, _ := json.Marshal(req)
resp, err := http.Post("http://localhost:18060/api/v1/publish_video",
"application/json", bytes.NewReader(body))
if err != nil {
panic("request failed: " + err.Error())
}
defer resp.Body.Close()
var out map[string]interface{}
_ = json.NewDecoder(resp.Body).Decode(&out)
if resp.StatusCode != http.StatusOK {
// API returns a unified error object
fmt.Printf("publish error: %v\n", out["error"])
return
}
fmt.Printf("publish success: %v\n", out["data"])
}
Key Source Files for Troubleshooting
Understanding the codebase structure accelerates debugging. Focus on these files when troubleshooting publishing issues in xiaohongshu-mcp:
| File | Role |
|---|---|
xiaohongshu/publish.go |
Core image-note publishing flow – navigation, image upload, title/content handling, schedule, visibility, original flag, product binding, final submit. Contains mustClickPublishTab, removePopCover, waitForUploadComplete, and checkTitleMaxLength. |
xiaohongshu/publish_video.go |
Video-note publishing – video upload, waiting for processing, and reuse of common UI helpers. Implements uploadVideo and waitForPublishButtonClickable. |
xiaohongshu/login.go |
Login management and QR-code handling; required before any publish action. Check CheckLoginStatus and WaitForLogin for authentication issues. |
docs/API.md |
HTTP/MCP API specification – useful when troubleshooting via the external API rather than the Go SDK. |
routes.go |
Registers the HTTP endpoints that map to the publishing functions. |
README.md |
Quick start guide, environment setup, and known limitations. |
Summary
Troubleshooting publishing issues in xiaohongshu-mcp requires systematic verification of the browser automation pipeline built on go-rod. Key takeaways include:
- Authentication first: Always verify login status via
CheckLoginStatusbefore attempting publishes, as unauthenticated sessions fail silently during navigation. - DOM cleanliness: Remove blocking pop-overs using
removePopCoveror manual intervention whenisElementBlockeddetects interference with the publish tab. - Selector maintenance: Update CSS selectors in
waitForUploadCompleteandconfirmOriginalDeclarationwhen Xiaohongshu UI changes cause "element not found" errors. - Content constraints: Respect title and content length limits enforced by
checkTitleMaxLengthandcheckContentMaxLengthto avoid validation errors. - Visibility strings: Use exact Chinese strings (
公开可见,仅自己可见,仅互关好友可见) for visibility settings to prevent configuration failures.
Frequently Asked Questions
Why does the publish button remain disabled when uploading video?
The video publishing flow in xiaohongshu/publish_video.go uses waitForPublishButtonClickable to poll the button's disabled attribute and class name. If the button stays disabled, the video is likely still processing on Xiaohongshu's servers. Increase the maxWait timeout in the configuration or check the browser console for upload errors. Ensure the video file path is absolute and accessible, as uploadVideo performs os.Stat validation before attempting upload.
How do I fix "未找到发布 TAB" errors?
This error originates in mustClickPublishTab (publish.go L59-L62) when the selector for the publish tab returns no elements. First, manually navigate to https://creator.xiaohongshu.com/publish/publish?source=official and verify the tab exists. If Xiaohongshu has updated their UI, you must update the CSS selectors in the source code. Also check for pop-overs blocking the tab using removePopCover or isElementBlocked (publish.go L35-L41).
What causes image upload timeouts and how can I resolve them?
Image upload timeouts occur in waitForUploadComplete (publish.go L43-L71) when the expected number of preview elements (matching .img-preview-area .pr) fails to appear within the timeout window. This usually indicates either slow network conditions to Xiaohongshu's CDN or a changed DOM structure. Verify that your image files exist at the specified paths before upload begins, as the code checks os.Stat early in the flow. If the CSS selector has changed, update the selector string in waitForUploadComplete and recompile.
Where can I find detailed error logs when publishing fails?
The xiaohongshu-mcp library uses github.com/pkg/errors to wrap errors with stack traces throughout the publishing pipeline. When action.Publish() returns an error, inspect the error string for references to specific functions like mustClickPublishTab, uploadImages, or submitPublish. For HTTP API users, check the JSON response body for the "error" field. Additionally, enable structured logging in your Go application to capture slog.Info outputs from the library, which log key milestones like "图片已提交上传" (images submitted for upload) and upload completion counts.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →