siyuan-note/siyuan · error

exporting special files is not supported

Error message

exporting special files is not supported

What it means

Returned by copyExportResource's WalkDir callback for any directory entry that is not a directory, not a regular file, and not a symlink — i.e. a 'special' file: device node, named pipe (FIFO), socket, or other non-regular inode. SiYuan cannot meaningfully zip these, so it refuses. This fires only for descendants of a resource folder (the top-level non-dir case goes to copyExportFile directly).

Source

Thrown at kernel/model/export.go:885

	}

	return filepath.WalkDir(source, func(current string, entry fs.DirEntry, walkErr error) error {
		if walkErr != nil {
			return walkErr
		}
		if entry.Type()&os.ModeSymlink != 0 {
			return errors.New("exporting symbolic links is not supported")
		}
		relativePath, relErr := filepath.Rel(source, current)
		if relErr != nil {
			return relErr
		}
		target := filepath.Join(destination, relativePath)
		if entry.IsDir() {
			return os.MkdirAll(target, 0755)
		}
		if !entry.Type().IsRegular() {
			return errors.New("exporting special files is not supported")
		}
		return copyExportFile(current, target)
	})
}

// copyExportFile 复制单个导出文件,并从加密资源容器恢复用户可见名称。
func copyExportFile(source, destination string) error {
	boxID := ExtractBoxIDFromAssetsPath(source)
	if boxID != "" && IsEncryptedBox(boxID) {
		diskName := filepath.Base(source)
		if originalName := LookupAssetOriginalName(boxID, diskName); originalName != "" {
			fileName := util.FilterFileName(filepath.Base(originalName))
			if fileName != "" && fileName != "." {
				destination = uniqueExportFilePath(filepath.Join(filepath.Dir(destination), fileName))
			}
		}
	}
	return copyAssetDecryptIfEncrypted(source, destination)

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Locate and remove the special file from the resource folder (find -type s, -type p, -type b, -type c).
  2. Ensure no process creates sockets/FIFOs inside the SiYuan assets directory.
  3. If the file is needed, move it outside the workspace and export only real assets.
  4. Audit: find <resource_folder> \( -type s -o -type p -o -type b -o -type c \) -ls

Example fix

# before — a stray socket file blocks the export
find workspace/data/notebook/assets -type s -ls
# after — remove special files before exporting
find workspace/data/notebook/assets \( -type s -o -type p -o -type b -o -type c \) -delete
Defensive patterns

Strategy: validation

Validate before calling

// Walk each resource folder and reject if any descendant is a special file
for _, p := range resourcePaths {
    full := filepath.Join(util.WorkspaceDir, p)
    info, err := os.Lstat(full)
    if err != nil || !info.IsDir() {
        continue
    }
    _ = filepath.WalkDir(full, func(_ string, e fs.DirEntry, _ error) error {
        if e != nil && !e.IsDir() && e.Type()&os.ModeSymlink == 0 && !e.Type().IsRegular() {
            return fmt.Errorf("special file inside resource folder: %s", e.Name())
        }
        return nil
    })
}

Prevention

When it happens

Trigger: ExportResources on a folder that contains a FIFO/socket/device file — e.g. a Linux workspace where a process created a socket file inside the assets dir, or a user accidentally copied a device node. The WalkDir entry's Type() is not IsRegular() and not ModeSymlink.

Common situations: An application created a .sock or FIFO inside the workspace assets folder. A backup restore included special files. Containerized deployments leaking /dev entries into a mounted volume.

Related errors


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