siyuan-note/siyuan · error
only local assets/... images are supported
Error message
only local assets/... images are supported
What it means
PrepareDocumentImage only accepts images stored under the workspace assets directory; after trimming, the path must start with assets/ (query string stripped). Any other shape — network URLs, absolute paths, or files in other directories — is rejected.
Solutions
- Copy the image into the workspace assets folder first so it gets an assets/... path
- Use the asset path as recorded in the document (strip any ?query suffix)
- For remote images, download and import them via the standard asset upload flow before analysis
Example fix
// before PrepareDocumentImage(docID, "https://example.com/x.jpg") // after PrepareDocumentImage(docID, "assets/x-20240101120000-ab12cd3.jpg")
Defensive patterns
Strategy: validation
Validate before calling
if !strings.HasPrefix(AssetPathWithoutQuery(assetPath), "assets/") { return errors.New("path must be a local assets/ image") } Type guard
func isLocalAssetPath(p string) bool { return strings.HasPrefix(AssetPathWithoutQuery(p), "assets/") } Try / catch
prepared, err := PrepareDocumentImage(docID, assetPath)
if err != nil && strings.Contains(err.Error(), "only local assets") { /* import the image, then retry */ } Prevention
- Only pass paths obtained from ListDocumentImages or document asset references
- Reject remote URLs and absolute paths in UI input handlers
- Strip query strings before comparison
When it happens
Trigger: Calling imageAnalyze / PrepareDocumentImage with values like "https://cdn.example.com/x.jpg", "/home/user/x.jpg", or "files/x.png".
Common situations: Passing a remote image URL from a web source; passing a notebook-local or temp-file path instead of a workspace asset; test TestPrepareDocumentImageRejectsNetworkImage exercises exactly this case.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- only global assets/... images are supported
- assetPath is not an image referenced by the document
- assetPath is required for analyze
- invalid asset path
- accessing assets in encrypted notebook
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/218881f0ff94a794.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/assets.go:458
seen := map[string]bool{}
for _, assetPath := range paths {
if !strings.HasPrefix(AssetPathWithoutQuery(assetPath), "assets/") || seen[assetPath] {
continue
}
seen[assetPath] = true
refs = append(refs, ImageArtifactRef{Kind: "image", Path: assetPath, DocumentID: bt.RootID})
}
return DocumentImageList{DocumentID: bt.RootID, Images: refs}, nil
}
// PrepareDocumentImage 校验并读取文档实际引用的本地资源图片,供当前模型直接接收图片输入。
func PrepareDocumentImage(documentID, assetPath string) (PreparedDocumentImage, error) {
assetPath = strings.TrimSpace(assetPath)
if assetPath == "" {
return PreparedDocumentImage{}, errors.New("assetPath is required for analyze")
}
if !strings.HasPrefix(AssetPathWithoutQuery(assetPath), "assets/") {
return PreparedDocumentImage{}, errors.New("only local assets/... images are supported")
}
bt, err := resolveMultimodalDocument(documentID)
if err != nil {
return PreparedDocumentImage{}, err
}
if !documentReferencesImage(bt.RootID, assetPath) {
return PreparedDocumentImage{}, errors.New("assetPath is not an image referenced by the document")
}
data, err := ReadAssetBytesInBox(bt.BoxID, assetPath)
if err != nil {
return PreparedDocumentImage{}, fmt.Errorf("read image failed: %w", err)
}
prepared, err := util.PrepareModelImage(
data, documentImageMaxBytes, documentImageMaxPixels, documentImageMaxEdge,
)
if err != nil {
return PreparedDocumentImage{}, err
}View on GitHub (pinned to 9f775e8a12)