siyuan-note/siyuan · error
marketplace package contains an invalid path
Error message
marketplace package contains an invalid path
What it means
A zip entry's name is empty or begins with a forward slash (absolute path). Thrown by extractLocalPackageItem (kernel/bazaar/local.go:130-132) after normalising backslashes to slashes. Absolute or empty entry names are rejected outright because they cannot map cleanly into the destination tree.
Source
Thrown at kernel/bazaar/local.go:132
}
}
if err = os.MkdirAll(destination, 0755); err != nil {
return err
}
var extractedTotal uint64
for _, item := range reader.File {
if err = extractLocalPackageItem(item, destination, &extractedTotal); err != nil {
return err
}
}
return nil
}
func extractLocalPackageItem(item *zip.File, destination string, extractedTotal *uint64) error {
name := strings.ReplaceAll(item.Name, "\\", "/")
if name == "" || strings.HasPrefix(name, "/") {
return errors.New("marketplace package contains an invalid path")
}
destinationPath := filepath.Join(destination, filepath.FromSlash(name))
if !gulu.File.IsSubPath(destination, destinationPath) {
return errors.New("marketplace package contains an invalid path")
}
mode := item.Mode()
if mode&os.ModeSymlink != 0 || (!mode.IsRegular() && !mode.IsDir()) {
return errors.New("marketplace package contains an unsupported file")
}
if mode.IsDir() {
return os.MkdirAll(destinationPath, 0755)
}
if err := os.MkdirAll(filepath.Dir(destinationPath), 0755); err != nil {
return err
}
source, err := item.Open()View on GitHub (pinned to 251596fc0d)
Solutions
- Re-create the archive using relative paths (cd into the package dir before zipping)
- Verify entry names with `unzip -l <path>` — none should start with /
- If generating the zip programmatically, set zip.FileHeader.Name to a relative path
Example fix
# before: absolute paths leak into entry names zip -r pkg.zip /home/user/myplugin # after: zip from inside the package directory so names are relative cd /home/user/myplugin && zip -r ../pkg.zip .
Defensive patterns
Strategy: validation
Validate before calling
func assertEntryNamesRelative(path string) error {
r, err := zip.OpenReader(path)
if err != nil { return err }
defer r.Close()
for _, f := range r.File {
n := strings.ReplaceAll(f.Name, "\\", "/")
if n == "" || strings.HasPrefix(n, "/") {
return fmt.Errorf("entry name invalid: %q", f.Name)
}
}
return nil
} Try / catch
if err != nil { return fmt.Errorf("package layout invalid: %w", err) } Prevention
- Always zip from inside the package directory so entry names are relative
- Inspect `unzip -l` output and reject any entry starting with /
- Set zip.FileHeader.Name to a relative path when generating archives in code
When it happens
Trigger: ExtractLocalPackage decompresses an archive that contains an entry whose Name is "" or starts with "/". This typically comes from zipping with absolute paths or from a corrupt/crafted central directory.
Common situations: The author zipped files with absolute paths (e.g. `zip -r pkg.zip /home/user/...`), producing leading-slash entry names; a tool emitted a malformed entry.
Related errors
- marketplace package is too large
- marketplace package contains an unsupported file
- invalid marketplace package archive
- marketplace package archive is empty
- marketplace package contains too many files
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/b6533392a2ebc9a1.
Report an issue: GitHub.