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
- Make sure the document exists and is open/indexed, then retry - the message itself says 'reopen the document'
- Use the doc id exactly as returned by the creation API and let indexing settle (wait for the kernel index task to finish)
- Verify the id via /api/query/block or /api/block/getBlockInfo before inserting
- 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
- Wait for doc indexing to commit before inserting assets (or open the doc in the editor first)
- Use the id returned by the doc-creation API, unmodified
- Verify you are on the workspace that actually contains the doc
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
- block not found
- duplicate document ID
- tree not found
- 0
- Account authentication failed, please login again
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)