siyuan-note/siyuan · error

Failed to insert asset file, please reopen the document

Error message

Failed to insert asset file, please reopen the document

What it means

InsertAssetBytes (kernel/model/upload.go:36) writes in-memory asset data directly into the target document's assets directory. Its first step is treenode.GetBlockTree(id); a nil entry means the kernel blocktree does not know this doc/block id, so the assets dir cannot be computed and the localized message Conf.Language(71) - "Failed to insert asset file, please reopen the document" - is returned.

Solutions

  1. Make sure the document exists and is open/indexed, then retry - the message itself says 'reopen the document'
  2. Use the doc id exactly as returned by the creation API and let indexing settle (wait for the kernel index task to finish)
  3. Verify the id via /api/query/block or /api/block/getBlockInfo before inserting
  4. If it persists, rebuild the index (设置 - 搜索 - 重建索引)
Defensive patterns

Strategy: retry

Validate before calling

// Confirm the target doc resolves before inserting:
// POST /api/query/block {"stmt": "SELECT * FROM blocks WHERE id='<docID>'"}
// Non-empty result -> blocktree knows the doc; InsertAssetBytes will resolve the assets dir.

Try / catch

assetPath, created, err := model.InsertAssetBytes(id, name, data)
if err != nil && err.Error() == model.Conf.Language(71) {
	// doc not indexed yet: open/reopen the doc, wait for indexing, retry once or twice with backoff
}

Prevention

When it happens

Trigger: Inserting an asset for a document whose id is not indexed yet (brand-new doc before the index queue commits, kernel still booting/indexing), a stale id after the doc was deleted, or an id from a different workspace.

Common situations: Agents/plugins inserting assets immediately after creating a document without waiting for indexing; retries against the wrong workspace; kernel just started and indexing is in progress.

Related errors


AI-assisted analysis of siyuan-note/siyuan@afa823b6b4 (2026-08-18). Data as JSON: /api/errors/8a6ae83e183dbd5a. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/upload.go:43

	"path"
	"path/filepath"
	"strings"

	"github.com/88250/gulu"
	"github.com/88250/lute/ast"
	"github.com/gin-gonic/gin"
	"github.com/siyuan-note/filelock"
	"github.com/siyuan-note/logging"
	"github.com/siyuan-note/siyuan/kernel/cache"
	"github.com/siyuan-note/siyuan/kernel/treenode"
	"github.com/siyuan-note/siyuan/kernel/util"
)

// InsertAssetBytes 将内存中的资源直接写入目标文档资源目录,避免生成内容经过明文临时文件。
func InsertAssetBytes(id, fileName string, data []byte) (assetPath string, created bool, err error) {
	bt := treenode.GetBlockTree(id)
	if bt == nil {
		return "", false, errors.New(Conf.Language(71))
	}
	if len(data) == 0 {
		return "", false, errors.New("asset data is empty")
	}

	baseName := filepath.Base(fileName)
	fName := util.FilterUploadFileName(baseName)
	ext := strings.ToLower(filepath.Ext(fName))
	fName = strings.TrimSuffix(fName, filepath.Ext(fName)) + ext
	if fName == "" || fName == "." || ext == "" {
		return "", false, errors.New("invalid asset filename")
	}

	docDirLocalPath := filepath.Join(util.DataDir, bt.BoxID, path.Dir(bt.Path))
	assetsDirPath := getAssetsDir(filepath.Join(util.DataDir, bt.BoxID), docDirLocalPath)
	if err = os.MkdirAll(assetsDirPath, 0755); err != nil {
		return "", false, err
	}

View on GitHub (pinned to afa823b6b4)