siyuan-note/siyuan · error

assetPath is not an image referenced by the document

Error message

assetPath is not an image referenced by the document

What it means

Returned by PrepareDocumentImage when documentReferencesImage(rootID, assetPath) is false — i.e. the AST of the resolved document does not contain a NodeImage whose link destination equals the requested asset. This is a security/integrity guard: it prevents a caller from reading arbitrary asset files by claiming they belong to a document.

Source

Thrown at kernel/model/assets.go:392

	}
	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
	}
	return PreparedDocumentImage{
		Artifact: ImageArtifactRef{Kind: "image", Path: assetPath, DocumentID: bt.RootID},
		Data:     prepared.Data,
		MIMEType: prepared.MIMEType,
		Prepared: prepared,
	}, nil
}

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Call ListDocumentImages(documentID) and pass only one of the returned ImageArtifactRef.Path values.
  2. If the asset was renamed/moved, re-insert it into the document so the AST references it, then retry.
  3. Do not construct asset paths by hand or copy them from another document.

Example fix

// before — caller hardcodes a guessed path
prepared, err := model.PrepareDocumentImage(docID, "assets/guess.png")

// after — caller enumerates actually-referenced images first
imgs, err := model.ListDocumentImages(docID)
if err != nil { return err }
if len(imgs.Images) == 0 { return errors.New("document has no images") }
prepared, err := model.PrepareDocumentImage(docID, imgs.Images[0].Path)
Defensive patterns

Strategy: validation

Validate before calling

// Fetch the document's actual images and only accept paths from that set.
imgs, err := model.ListDocumentImages(documentID)
if err != nil { return err }
allowed := make(map[string]struct{}, len(imgs.Images))
for _, ref := range imgs.Images {
    allowed[model.AssetPathWithoutQuery(ref.Path)] = struct{}{}
}
if _, ok := allowed[model.AssetPathWithoutQuery(assetPath)]; !ok {
    return errors.New("asset is not referenced by this document")
}

Prevention

When it happens

Trigger: Calling PrepareDocumentImage with a valid-looking assets/... path that exists on disk but is not actually embedded in the document; using a path from a different document; passing a stale path after the image was removed from the doc; passing a path that differs only by query string from the embedded form.

Common situations: An AI tool cached an asset path from a previous doc version and the image was since deleted/replaced; a cross-document reference where the caller mixed up rootIDs; an attempt to exfiltrate an unrelated asset via the vision pipeline.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/37624d1b4d412a39. Report an issue: GitHub.