siyuan-note/siyuan · error
image operation failed
Error message
image operation failed
What it means
imageError builds the error CallToolResult for MCP image tools and substitutes this default message when the caller passes an empty message. It guarantees the tool result is always marked IsError with non-empty text, since an error result with blank content is useless to the MCP client.
Solutions
- Always pass a descriptive message (or the underlying err.Error()) into imageError instead of ""
- Use imageResultForError(err) for real error values so classification (e.g. IsImageExecutionUnknown) and messaging are handled
- Add a guard/log at call sites where the message is built dynamically to catch empty strings early
Example fix
// before
return imageError("")
// after
return imageResultForError(fmt.Errorf("render image failed: %w", err)) Defensive patterns
Strategy: try-catch
Validate before calling
if (!message || message.trim() === '') {
message = 'image operation failed'; // or derive from err
} Try / catch
try {
return await imageToolCall(args);
} catch (err) {
return imageResultForError(err); // classifies unknown-execution errors and keeps a non-empty message
} Prevention
- Use imageResultForError for real error values instead of hand-built imageError calls
- Include the underlying err.Error() text in the message
- Assert in tests that error results always carry non-empty text
When it happens
Trigger: Any image tool failure path (imageHandler, imageList, runImageOperation, imageJSON, imageResultForError, imageUnknown) that reaches imageError with an empty message — typically an error value whose Error() is "" or a branch that forgets to set a message.
Common situations: Wrapping errors that stringify to empty; swallowing the underlying error into an empty variable; callers constructing errors from nil/empty fields; missing i18n or formatting that leaves the message blank.
Related errors
- attr must be a string or null (got %T)
- BASE64_IMAGE_SIZE_LIMIT
- command is required for stdio server
- configuration is not initialized
- connect
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/3ebf76cc127877b3.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/mcp/tools/image.go:346
bt := treenode.GetBlockTree(documentID)
if bt == nil {
return false
}
_, err := model.GetAssetAbsPathInBox(assetPath, bt.BoxID)
return err == nil
}
func imageJSON(value any) CallToolResult {
data, err := json.Marshal(value)
if err != nil {
return imageError(err.Error())
}
return CallToolResult{Content: []ContentItem{{Type: "text", Text: string(data)}}}
}
func imageError(message string) CallToolResult {
if message == "" {
message = errors.New("image operation failed").Error()
}
return CallToolResult{Content: []ContentItem{{Type: "text", Text: message}}, IsError: true}
}
func imageResultForError(err error) CallToolResult {
if model.IsImageExecutionUnknown(err) {
return imageUnknown(err.Error())
}
return imageError(err.Error())
}
func imageUnknown(message string) CallToolResult {
result := imageError(message)
result.ExecutionUnknown = true
return result
}
View on GitHub (pinned to 9f775e8a12)