{"record":{"id":"218881f0ff94a794","repo":"siyuan-note/siyuan","slug":"only-local-assets-images-are-supported","errorCode":null,"errorMessage":"only local assets/... images are supported","messagePattern":"only local assets/\\.\\.\\. images are supported","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/assets.go","lineNumber":458,"sourceCode":"\tseen := map[string]bool{}\n\tfor _, assetPath := range paths {\n\t\tif !strings.HasPrefix(AssetPathWithoutQuery(assetPath), \"assets/\") || seen[assetPath] {\n\t\t\tcontinue\n\t\t}\n\t\tseen[assetPath] = true\n\t\trefs = append(refs, ImageArtifactRef{Kind: \"image\", Path: assetPath, DocumentID: bt.RootID})\n\t}\n\treturn DocumentImageList{DocumentID: bt.RootID, Images: refs}, nil\n}\n\n// PrepareDocumentImage 校验并读取文档实际引用的本地资源图片，供当前模型直接接收图片输入。\nfunc PrepareDocumentImage(documentID, assetPath string) (PreparedDocumentImage, error) {\n\tassetPath = strings.TrimSpace(assetPath)\n\tif assetPath == \"\" {\n\t\treturn PreparedDocumentImage{}, errors.New(\"assetPath is required for analyze\")\n\t}\n\tif !strings.HasPrefix(AssetPathWithoutQuery(assetPath), \"assets/\") {\n\t\treturn PreparedDocumentImage{}, errors.New(\"only local assets/... images are supported\")\n\t}\n\tbt, err := resolveMultimodalDocument(documentID)\n\tif err != nil {\n\t\treturn PreparedDocumentImage{}, err\n\t}\n\tif !documentReferencesImage(bt.RootID, assetPath) {\n\t\treturn PreparedDocumentImage{}, errors.New(\"assetPath is not an image referenced by the document\")\n\t}\n\tdata, err := ReadAssetBytesInBox(bt.BoxID, assetPath)\n\tif err != nil {\n\t\treturn PreparedDocumentImage{}, fmt.Errorf(\"read image failed: %w\", err)\n\t}\n\tprepared, err := util.PrepareModelImage(\n\t\tdata, documentImageMaxBytes, documentImageMaxPixels, documentImageMaxEdge,\n\t)\n\tif err != nil {\n\t\treturn PreparedDocumentImage{}, err\n\t}","sourceCodeStart":440,"sourceCodeEnd":476,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/assets.go#L440-L476","documentation":"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.","triggerScenarios":"Calling imageAnalyze / PrepareDocumentImage with values like \"https://cdn.example.com/x.jpg\", \"/home/user/x.jpg\", or \"files/x.png\".","commonSituations":"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.","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"],"exampleFix":"// before\nPrepareDocumentImage(docID, \"https://example.com/x.jpg\")\n// after\nPrepareDocumentImage(docID, \"assets/x-20240101120000-ab12cd3.jpg\")","handlingStrategy":"validation","validationCode":"if !strings.HasPrefix(AssetPathWithoutQuery(assetPath), \"assets/\") { return errors.New(\"path must be a local assets/ image\") }","typeGuard":"func isLocalAssetPath(p string) bool { return strings.HasPrefix(AssetPathWithoutQuery(p), \"assets/\") }","tryCatchPattern":"prepared, err := PrepareDocumentImage(docID, assetPath)\nif err != nil && strings.Contains(err.Error(), \"only local assets\") { /* import the image, then retry */ }","preventionTips":["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"],"tags":["go","validation","assets","ai"],"backgroundTag":"invalid-argument-value","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}