siyuan-note/siyuan · error
no entry
Error message
no entry
What it means
During Upload of a directory-style asset, the kernel extracts the bundle into a temp directory and then reads its entries. If the extracted second-level temp directory (tmpDir2) contains no entries at all, it treats the archive as empty/invalid, logs "read dir [...] failed: no entry", records the failure with "no entry", and cleans up both temp directories.
Source
Thrown at kernel/model/upload.go:488
tmpDir2 := filepath.Join(util.TempDir, "convert", "zip", gulu.Rand.String(7))
if err = gulu.Zip.Unzip(writePath, tmpDir2); err != nil {
recordFailure(index, file.Filename, fName, err)
_ = os.RemoveAll(tmpDir)
_ = os.RemoveAll(tmpDir2)
continue
}
entries, readErr := os.ReadDir(tmpDir2)
if nil != readErr {
logging.LogErrorf("read dir [%s] failed: %s", tmpDir2, readErr)
recordFailure(index, file.Filename, fName, readErr)
_ = os.RemoveAll(tmpDir)
_ = os.RemoveAll(tmpDir2)
continue
}
if 1 > len(entries) {
logging.LogErrorf("read dir [%s] failed: no entry", tmpDir2)
noEntryErr := errors.New("no entry")
recordFailure(index, file.Filename, fName, noEntryErr)
_ = os.RemoveAll(tmpDir)
_ = os.RemoveAll(tmpDir2)
continue
}
dirName := entries[0].Name()
srcDir := filepath.Join(tmpDir2, dirName)
entries, readErr = os.ReadDir(srcDir)
if nil != readErr {
logging.LogErrorf("read dir [%s] failed: %s", filepath.Join(tmpDir2, entries[0].Name()), readErr)
recordFailure(index, file.Filename, fName, readErr)
_ = os.RemoveAll(tmpDir)
_ = os.RemoveAll(tmpDir2)
continue
}
destDir := filepath.Join(assetsDirPath, fName)
if copyErr := copyRTFDEntries(entries, srcDir, destDir, gulu.File.Copy); nil != copyErr {
logging.LogErrorf("copy RTFD directory [%s] failed: %s", srcDir, copyErr)View on GitHub (pinned to 8641553a1f)
Solutions
- Verify the uploaded archive is valid and non-empty; re-create and re-upload it.
- Ensure the bundle layout matches the expected structure: one top-level directory directly containing the asset files (no extra nesting).
- If the asset genuinely has no content, upload individual files instead of an archive.
Example fix
// before zip -r note.rtfd.zip note.rtfd/old/ // wrong nesting / empty payload // after zip -r note.rtfd.zip note.rtfd/ // note.rtfd dir with files inside
Defensive patterns
Strategy: validation
Validate before calling
func validateBundle(zipPath string) error {
zr, err := zip.OpenReader(zipPath)
if err != nil { return err }
defer zr.Close()
if len(zr.File) == 0 { return errors.New("archive is empty") }
for _, f := range zr.File {
if !f.FileInfo().IsDir() { return nil }
}
return errors.New("archive contains only directories")
} Try / catch
_, _, failed, err := model.Upload(...)
for _, f := range failed {
if f.Error == "no entry" {
logging.LogWarnf("archive %s extracted to nothing; verify bundle and retry", f.Name)
}
} Prevention
- Validate archives are non-empty and contain files before uploading.
- Keep the bundle layout simple: one top-level directory with the asset files directly inside.
- Check archive integrity (e.g. zip -T) when bundles are produced by scripts.
When it happens
Trigger: Uploading an archive/bundle (needUnzip2Dir path) whose extracted contents are empty or whose structure nests the real files deeper than one directory level, so the single directory the code expects (entries[0]) is missing.
Common situations: Corrupted or zero-byte .zip/.rtfd files; bundles zipped with an extra wrapping folder so the expected first entry is not a directory; archives whose payload was stripped by the packaging tool.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- symlink resolves into encrypted notebook [%s]
- Account authentication failed, please login again
- Upload failed: %s
- Failed to insert asset file, please reopen the document
- unzip failed: %s
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/ba024e3084d741f9.
Report an issue: GitHub.