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

  1. Check len(data) > 0 before calling InsertAssetBytes
  2. Trace the data source — verify the reader/file that populated the byte slice actually produced bytes
  3. 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

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


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