{"record":{"id":"9ffd13dd706e04f5","repo":"siyuan-note/siyuan","slug":"multiple-marketplace-package-manifests-found","errorCode":null,"errorMessage":"multiple marketplace package manifests found","messagePattern":"multiple marketplace package manifests found","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/bazaar/local.go","lineNumber":67,"sourceCode":"\ttempPath := filepath.Join(util.TempDir, \"bazaar\", \"local\", gulu.Rand.String(7))\n\tcleanup = func() { _ = os.RemoveAll(tempPath) }\n\tif err = extractLocalPackageArchive(archivePath, tempPath); err != nil {\n\t\tcleanup()\n\t\treturn\n\t}\n\n\tpackagePath, err = localPackageRoot(tempPath)\n\tif err != nil {\n\t\tcleanup()\n\t\treturn\n\t}\n\n\tvar manifestPath string\n\tfor manifestName, packageType := range localPackageManifests {\n\t\tcandidate := filepath.Join(packagePath, manifestName)\n\t\tif info, statErr := os.Stat(candidate); statErr == nil && info.Mode().IsRegular() {\n\t\t\tif manifestPath != \"\" {\n\t\t\t\terr = errors.New(\"multiple marketplace package manifests found\")\n\t\t\t\tcleanup()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tpkgType = packageType\n\t\t\tmanifestPath = candidate\n\t\t}\n\t}\n\tif manifestPath == \"\" {\n\t\terr = errors.New(\"marketplace package manifest not found\")\n\t\tcleanup()\n\t\treturn\n\t}\n\n\tpkg, err = ParsePackageJSON(manifestPath)\n\tif err != nil || pkg == nil {\n\t\terr = errors.New(\"invalid marketplace package manifest\")\n\t\tcleanup()\n\t}","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/bazaar/local.go#L49-L85","documentation":"ExtractLocalPackage scans the extracted package root for exactly one of plugin.json, theme.json, icon.json, template.json, or widget.json. If a regular file matching two or more of these manifest names exists in the same root, it cannot decide the package type and throws this error. The temp extraction is cleaned up before returning.","triggerScenarios":"Calling ExtractLocalPackage (or InstallLocalBazaarPackage) on a zip whose package root contains e.g. both plugin.json and theme.json as regular files.","commonSituations":"A developer merges several package types into one directory before packaging; a zip accidentally bundles manifest files left over from another project; CI copies multiple manifests into the build output.","solutions":["Remove all manifest files from the package root except the one matching the intended package type","Repackage the zip with only one manifest (plugin.json XOR theme.json XOR icon.json XOR template.json XOR widget.json)","Check .gitignore/build scripts so other projects' manifests are not copied into the output"],"exampleFix":"// before: package root contains plugin.json AND theme.json\n// after:\nmy-plugin/\n  plugin.json\n  index.js\n  ...","handlingStrategy":"validation","validationCode":"const allowed = [\"plugin.json\",\"theme.json\",\"icon.json\",\"template.json\",\"widget.json\"];\nconst found = allowed.filter(f => fs.existsSync(path.join(pkgRoot, f)) && fs.statSync(path.join(pkgRoot, f)).isFile());\nif (found.length !== 1) throw new Error(\"package must contain exactly one manifest, found: \" + found.join(\",\"));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep exactly one manifest per package directory","Check the zip listing before distributing","Clean stale manifests from build output"],"tags":["bazaar","package","manifest","validation"],"backgroundTag":"conflicting-config-options","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}