{"record":{"id":"b3a6f199646d18d8","repo":"siyuan-note/siyuan","slug":"marketplace-package-manifest-must-be-at-the-archiv","errorCode":null,"errorMessage":"marketplace package manifest must be at the archive root or its only top-level directory","messagePattern":"marketplace package manifest must be at the archive root or its only top-level directory","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/bazaar/local.go","lineNumber":186,"sourceCode":"\t\treturn errors.New(\"marketplace package contains a file that is too large\")\n\t}\n\tif uint64(written) > maxLocalPackageExtractSize-*extractedTotal {\n\t\treturn errors.New(\"marketplace package is too large\")\n\t}\n\t*extractedTotal += uint64(written)\n\treturn nil\n}\n\nfunc localPackageRoot(extractPath string) (string, error) {\n\tif hasLocalPackageManifest(extractPath) {\n\t\treturn extractPath, nil\n\t}\n\tentries, err := os.ReadDir(extractPath)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tif len(entries) != 1 || !entries[0].IsDir() {\n\t\treturn \"\", errors.New(\"marketplace package manifest must be at the archive root or its only top-level directory\")\n\t}\n\troot := filepath.Join(extractPath, entries[0].Name())\n\tif !hasLocalPackageManifest(root) {\n\t\treturn \"\", errors.New(\"marketplace package manifest not found\")\n\t}\n\treturn root, nil\n}\n\nfunc hasLocalPackageManifest(root string) bool {\n\tfor manifestName := range localPackageManifests {\n\t\tif info, err := os.Stat(filepath.Join(root, manifestName)); err == nil && info.Mode().IsRegular() {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n","sourceCodeStart":168,"sourceCodeEnd":203,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/bazaar/local.go#L168-L203","documentation":"localPackageRoot could not find a recognized manifest at the extraction root, and the root does not contain exactly one top-level directory entry. Thrown at kernel/bazaar/local.go:185-186 when len(entries) != 1 or the single entry is not a directory. Packages must lay out as either manifest-at-root or a single wrapping directory.","triggerScenarios":"After extraction, the extract root has zero, two, or more top-level entries, or a single non-directory entry, and none of the recognized manifests (plugin.json/theme.json/icon.json/template.json/widget.json) sits directly at the root.","commonSituations":"The author zipped the contents flat (manifest buried in a subdir) alongside sibling folders; the archive wraps multiple top-level projects; the manifest sits one level too deep or too shallow.","solutions":["Restructure the archive so the manifest is either at the zip root or inside exactly one top-level directory","Remove sibling top-level entries (README at root is fine only if there is a single wrapping dir)","Re-zip from the correct level so the layout is root/manifest.json or root/<pkgdir>/manifest.json"],"exampleFix":"# before: two top-level entries, manifest inside one of them\nmyplugin/\nREADME.md\n# -> fails: len(entries) == 2\n\n# after: single top-level dir holding manifest + README\nmyplugin/plugin.json\nmyplugin/README.md","handlingStrategy":"validation","validationCode":"// After test-extraction, confirm layout is manifest-at-root or single wrapping dir\nfunc assertLayout(extractPath string) error {\n    if hasManifest(extractPath) { return nil }\n    es, err := os.ReadDir(extractPath)\n    if err != nil { return err }\n    if len(es) != 1 || !es[0].IsDir() {\n        return errors.New(\"need manifest at root or exactly one top-level dir\")\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if _, err := localPackageRoot(tempPath); err != nil {\n    cleanup()\n    return fmt.Errorf(\"package layout rejected: %w\", err)\n}","preventionTips":["Standardize on one of two layouts: manifest at zip root, or a single wrapping directory","Avoid mixing top-level files and sibling directories in the archive","Document the expected layout in the package author guide"],"tags":["zip","archive","bazaar","marketplace","manifest","layout"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}