siyuan-note/siyuan · error
asset data is empty
Error message
asset data is empty
What it means
Thrown by InsertAssetBytes when the data byte slice has length zero. The function exists to write in-memory asset bytes directly to disk (bypassing temp files), so empty data is a programming error — there is nothing to write. This guard runs before any filesystem operation.
Source
Thrown at kernel/model/upload.go:46
"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
}
reader := bytes.NewReader(data)
hash, err := util.GetEtagByHandle(reader, int64(len(data)))View on GitHub (pinned to 251596fc0d)
Solutions
- Check len(data) > 0 before calling InsertAssetBytes
- Trace the data source — verify the reader/file that populated the byte slice actually produced bytes
- If the asset is legitimately zero-length, decide whether it should be skipped rather than inserted
Example fix
// before
assetPath, created, err := model.InsertAssetBytes(id, name, data)
// after
if len(data) == 0 {
return errors.New("cannot insert empty asset")
}
assetPath, created, err := model.InsertAssetBytes(id, name, data) Defensive patterns
Strategy: validation
Validate before calling
if len(data) == 0 {
return errors.New("cannot insert empty asset data")
}
assetPath, created, err := model.InsertAssetBytes(id, fileName, data) Prevention
- Validate that byte buffers are non-empty before passing to asset insertion APIs
- Log the data source and size when asset data is unexpectedly empty to trace upstream read failures
- For HTTP upload handlers, reject zero-length request bodies before they reach InsertAssetBytes
When it happens
Trigger: Passing a nil or zero-length []byte to InsertAssetBytes. This happens when an upstream read returned no data (e.g., an empty file upload, a failed network read that produced an empty buffer, or a bug that initializes a byte slice but never populates it).
Common situations: The upstream caller read from a closed reader, an HTTP multipart upload had a zero-length body, or the asset data pipeline dropped the buffer before reaching InsertAssetBytes.
Related errors
- invalid asset filename
- no file found
- field [file] or [url] must not be empty
- Failed to insert asset file, please reopen the document
- task list item marker length should be 1
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/26311b8fad7ad4e3.
Report an issue: GitHub.