{"record":{"id":"0a9571107cd1dd74","repo":"siyuan-note/siyuan","slug":"invalid-marketplace-package-manifest","errorCode":null,"errorMessage":"invalid marketplace package manifest","messagePattern":"invalid marketplace package manifest","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/bazaar/local.go","lineNumber":83,"sourceCode":"\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}\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}","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/bazaar/local.go#L65-L101","documentation":"After locating the manifest, ExtractLocalPackage parses it with ParsePackageJSON. If parsing fails or returns nil, the manifest exists but is not a valid marketplace package JSON (bad JSON syntax, missing required fields), so the whole extraction is aborted with this generic error and temp files are removed.","triggerScenarios":"Calling ExtractLocalPackage with a package whose plugin.json/theme.json/icon.json/template.json/widget.json contains malformed JSON, is empty, or lacks required fields such as name/author/version.","commonSituations":"Hand-edited manifest with a trailing comma; file saved in wrong encoding (UTF-16/BOM); manifest fields removed when copying a template; JSONC comments left in the manifest.","solutions":["Validate the manifest as strict JSON (no comments, no trailing commas), e.g. with jq or a JSON linter","Ensure required package fields (name, author, version, etc.) are present and non-empty","Re-save the manifest as UTF-8 without BOM","Compare against a known-good sample manifest of the same package type"],"exampleFix":"// before: { \"name\": \"x\", \"version\": \"1.0\", }  // trailing comma\n// after: { \"name\": \"x\", \"version\": \"1.0.0\" }","handlingStrategy":"validation","validationCode":"const raw = fs.readFileSync(path.join(pkgRoot, \"plugin.json\"), \"utf8\").replace(/^\\uFEFF/, \"\");\nconst manifest = JSON.parse(raw);\nif (!manifest.name || !manifest.version || !manifest.author) throw new Error(\"manifest missing required fields\");","typeGuard":null,"tryCatchPattern":"try { await installLocalPackage(zipPath); } catch (e) { if (String(e).includes(\"invalid marketplace package manifest\")) { JSON.parse(fs.readFileSync(\"plugin.json\", \"utf8\")); } }","preventionTips":["Run the manifest through a JSON linter before packaging","Keep required fields (name, author, version) present","Save as UTF-8 without BOM; no JSONC comments"],"tags":["bazaar","package","manifest","json","validation"],"backgroundTag":"schema-validation-failed","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"}