{"record":{"id":"375d6a2a39a7abcf","repo":"siyuan-note/siyuan","slug":"marketplace-package-contains-too-many-files","errorCode":null,"errorMessage":"marketplace package contains too many files","messagePattern":"marketplace package contains too many files","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/bazaar/local.go","lineNumber":100,"sourceCode":"\tif err != nil || pkg == nil {\n\t\terr = errors.New(\"invalid marketplace package manifest\")\n\t\tcleanup()\n\t}\n\treturn\n}\n\nfunc extractLocalPackageArchive(archivePath, destination string) error {\n\treader, err := zip.OpenReader(archivePath)\n\tif err != nil {\n\t\treturn errors.New(\"invalid marketplace package archive\")\n\t}\n\tdefer reader.Close()\n\n\tif len(reader.File) == 0 {\n\t\treturn errors.New(\"marketplace package archive is empty\")\n\t}\n\tif len(reader.File) > maxLocalPackageFileCount {\n\t\treturn errors.New(\"marketplace package contains too many files\")\n\t}\n\n\tvar declaredTotal uint64\n\tfor _, item := range reader.File {\n\t\tif item.UncompressedSize64 > maxLocalPackageFileSize {\n\t\t\treturn errors.New(\"marketplace package contains a file that is too large\")\n\t\t}\n\t\tif ^uint64(0)-declaredTotal < item.UncompressedSize64 {\n\t\t\treturn errors.New(\"marketplace package is too large\")\n\t\t}\n\t\tdeclaredTotal += item.UncompressedSize64\n\t\tif declaredTotal > maxLocalPackageExtractSize {\n\t\t\treturn errors.New(\"marketplace package is too large\")\n\t\t}\n\t}\n\n\tif err = os.MkdirAll(destination, 0755); err != nil {\n\t\treturn err","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/bazaar/local.go#L82-L118","documentation":"The package archive contains more than maxLocalPackageFileCount (10000) entries. Thrown by extractLocalPackageArchive (kernel/bazaar/local.go:99-100) as a resource/zip-bomb guard before any entry is read. The limit is a hard package constant; it is not configurable per call.","triggerScenarios":"ExtractLocalPackage receives a zip whose len(reader.File) exceeds 10000. Happens when the archive bundles a large dependency tree (e.g. node_modules, vendored libraries, generated assets).","commonSituations":"A theme/plugin author zipped the whole project including node_modules or .git; a build pipeline included generated file forests; a malicious archive deliberately inflates entry count.","solutions":["Exclude node_modules, .git, dist build caches, and other large trees before zipping","Reduce the package to only shipped files (manifest, source/assets, README)","If a legitimate package genuinely needs >10000 files, restructure it (split packages, prune duplicates)"],"exampleFix":"# before: zips everything including node_modules\nzip -r pkg.zip .\n\n# after: exclude heavy/unneeded trees\nzip -r pkg.zip . -x 'node_modules/*' '.git/*' '*/dist/*'","handlingStrategy":"validation","validationCode":"func assertFileCount(path string) error {\n    r, err := zip.OpenReader(path)\n    if err != nil { return err }\n    defer r.Close()\n    if len(r.File) > 10000 { return fmt.Errorf(\"archive has %d entries (>10000)\", len(r.File)) }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if _, pkg, src, cleanup, err := bazaar.ExtractLocalPackage(archivePath); err != nil {\n    cleanup()\n    return err\n}","preventionTips":["Always exclude node_modules, .git, and build caches when zipping packages","Run a pre-publish check counting zip entries against the 10000 cap","Treat an unexpectedly high entry count as a packaging bug, not a limit to raise"],"tags":["zip","archive","bazaar","zip-bomb","limits"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}