siyuan-note/siyuan · error

assetPath is required for analyze

Error message

assetPath is required for analyze

What it means

Validation guard in PrepareDocumentImage: fires when the assetPath argument is empty. Analyzing a document image requires a concrete asset path under assets/ to resolve and read; calling imageAnalyze (or the function directly, as tests do) without a path is the faulting input, distinct from later network-image rejection.

Solutions

  1. Populate assetPath with a document-referenced assets/... path before calling
  2. Trim and check the value on the client and show a validation message instead of sending the request
  3. Default the UI picker so it always supplies the currently selected image path

Example fix

// before
PrepareDocumentImage(docID, "")
// after
if assetPath == "" { return errors.New("choose an image first") }
PrepareDocumentImage(docID, assetPath)
Defensive patterns

Strategy: validation

Validate before calling

if strings.TrimSpace(assetPath) == "" { return errors.New("assetPath is required") }

Try / catch

prepared, err := PrepareDocumentImage(docID, assetPath)
if err != nil && strings.Contains(err.Error(), "assetPath is required") { return userFacingError("select an image first") }

Prevention

When it happens

Trigger: Calling imageAnalyze / PrepareDocumentImage with assetPath omitted or set to "" or " ".

Common situations: Client code reading the path from config or a form field that was left blank; forgetting to pass the field when building the JSON request body.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/f570ce0f893b7d4c. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/assets.go:455

		return DocumentImageList{}, fmt.Errorf("list document images failed: %w", err)
	}
	refs := make([]ImageArtifactRef, 0, len(paths))
	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,
	)

View on GitHub (pinned to 9f775e8a12)