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

  1. Copy the image into the workspace assets folder first so it gets an assets/... path
  2. Use the asset path as recorded in the document (strip any ?query suffix)
  3. 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

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


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)