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

  1. Verify the uploaded archive is valid and non-empty; re-create and re-upload it.
  2. Ensure the bundle layout matches the expected structure: one top-level directory directly containing the asset files (no extra nesting).
  3. 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

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


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/ba024e3084d741f9. Report an issue: GitHub.