siyuan-note/siyuan · error

export source [%s] is not a regular file

Error message

export source [%s] is not a regular file

What it means

Returned by copyExportFileToDestination (export.go:1201) when the export source path does not resolve to a regular file (os.Lstat shows it is a directory, symlink target, device, socket, etc.). The export copy logic only reads plain files; anything else — a missing file, a directory, a dangling symlink, a FIFO — is refused before opening to avoid hanging on special files or copying unintended content.

Source

Thrown at kernel/api/export.go:1202

	if err := copyExportFileToDestination(srcFullPath, dest); err != nil {
		logging.LogErrorf("copy export file [%s] to [%s] failed: %s", srcFullPath, dest, err)
		ret.Code = -1
		ret.Msg = err.Error()
		return
	}
}

func copyExportFileToDestination(src, dest string) (err error) {
	filelock.Lock(src)
	defer filelock.Unlock(src)

	srcInfo, err := os.Lstat(src)
	if err != nil {
		return err
	}
	if !srcInfo.Mode().IsRegular() {
		return fmt.Errorf("export source [%s] is not a regular file", src)
	}

	srcFile, err := os.Open(src)
	if err != nil {
		return err
	}
	defer srcFile.Close()

	destDir := filepath.Dir(dest)
	if err = os.MkdirAll(destDir, 0755); err != nil {
		return err
	}
	tmpFile, err := os.CreateTemp(destDir, ".siyuan-export-*.tmp")
	if err != nil {
		return err
	}
	tmpPath := tmpFile.Name()
	tmpClosed := false

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Verify the export source exists and is a regular file right before the copy step (os.Stat / check Mode().IsRegular()).
  2. Retry the full export operation (re-render) so the staging artifact is regenerated cleanly.
  3. Ensure no other process is clearing util.TempDir/export during export, and that the workspace temp dir has adequate free space and permissions.
  4. If the user-supplied destination triggered a path issue, confirm `dest` resolves under the intended directory and is not itself a directory.
Defensive patterns

Strategy: validation

Validate before calling

// Verify source is a regular file before invoking export copy
info, err := os.Lstat(src)
if err != nil || !info.Mode().IsRegular() {
  return fmt.Errorf("export source missing or not a regular file: %w", err)
}

Try / catch

try { await exportTo(dest); }
catch (e) {
  if (/not a regular file/.test(e.msg)) { await reRunExport(); /* retry with fresh artifact */ }
  else throw e;
}

Prevention

When it happens

Trigger: The export-to-disk endpoint (the one calling copyExportFileToDestination at export.go:1185) is invoked with a `srcFullPath` that Lstat's as non-regular: the temp export artifact was deleted/moved before copy, the path points at a directory, or a symlink resolves to a special file. A preceding export step failed to produce the expected rendered PDF/HTML/zip file.

Common situations: Concurrent cleanup or temp-dir eviction (e.g. another export, a crash, or a cleanup job) removing the staged export artifact between render and copy. Misconfigured export path pointing at a folder. Disk-full or permission error during staging that left a partial/zero-byte non-file entry. OS-level symlink inside the temp dir.

Related errors


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