CherryHQ/cherry-studio · error · Error
manifest.json not found in ${packageLabel} file
Error message
manifest.json not found in ${packageLabel} file What it means
Thrown after ZIP extraction when fs.existsSync(path.join(tempExtractDir, 'manifest.json')) is false. The package extracted successfully (no zip-slip, no extraction error) but no manifest.json entry was present at the archive root. The manifest is the contract every mcpb/dxt package must provide; without it the service cannot determine the server command, args, or version.
Source
Thrown at src/main/ai/mcp/McpPackageService.ts:530
throw new Error(`${packageLabel} file not found`)
}
// Extract the package file (which is a ZIP archive) to a temporary directory
logger.debug(`Extracting ${packageLabel} file: ${filePath}`)
const zip = new StreamZip.async({ file: filePath })
try {
// Reject any zip-slip entry before writing anything to disk.
assertZipEntriesWithin(Object.keys(await zip.entries()), tempExtractDir)
await zip.extract(null, tempExtractDir)
} finally {
await zip.close()
}
// Read and validate the manifest.json
const manifestPath = path.join(tempExtractDir, 'manifest.json')
if (!fs.existsSync(manifestPath)) {
throw new Error(`manifest.json not found in ${packageLabel} file`)
}
const manifestContent = fs.readFileSync(manifestPath, 'utf-8')
const parsedManifest: ParsedMcpPackageManifest = JSON.parse(manifestContent)
// Validate required fields in manifest
let manifest: McpPackageManifest
if (packageFormat === 'mcpb') {
if (!parsedManifest.manifest_version) {
throw new Error('Invalid manifest: missing manifest_version')
}
manifest = { ...parsedManifest, manifest_version: parsedManifest.manifest_version }
} else {
if (!parsedManifest.dxt_version) {
throw new Error('Invalid manifest: missing dxt_version')
}
manifest = { ...parsedManifest, dxt_version: parsedManifest.dxt_version }
}View on GitHub (pinned to 726446b54c)
Solutions
- Inspect the archive layout (unzip -l pkg.mcpb) and confirm manifest.json sits at the top level, not under a subdirectory.
- Re-zip from inside the package directory so entries are relative to the directory root (cd pkg && zip -r ../out.mcpb .).
- Ensure the file is named exactly manifest.json (case-sensitive) and is a JSON object, not a wrapper document.
Example fix
# before: zip created with parent dir $ unzip -l out.mcpb pkg/manifest.json pkg/server.js # after: zip from inside the dir $ cd pkg && zip -r ../out.mcpb . $ unzip -l ../out.mcpb manifest.json server.js
Defensive patterns
Strategy: validation
Validate before calling
import * as StreamZip from 'node-stream-zip'
import * as fs from 'fs'
import * as path from 'path'
async function archiveHasRootManifest(zipPath: string): Promise<boolean> {
const zip = new StreamZip.async({ file: zipPath })
try {
const entries = await zip.entries()
return Object.keys(entries).includes('manifest.json')
} finally {
await zip.close()
}
} Prevention
- When zipping a package, cd into the package directory first so entries are relative to the archive root (cd pkg && zip -r ../out.mcpb .).
- After building, run unzip -l out.mcpb and assert manifest.json appears at the top level (no prefix).
- Name the file exactly manifest.json (case-sensitive); do not use .jsonc or alternative spellings.
When it happens
Trigger: The .mcpb/.dxt archive unzips to a top-level folder (e.g. everything under pkg/) rather than to the archive root, so manifest.json lands at tempExtractDir/pkg/manifest.json; or the manifest was named differently (manifest.jsonc, package.json); or the archive was assembled without including the manifest.
Common situations: The zip was created with `zip -r out.mcpb mydir/` which preserves the mydir/ prefix; a build script zipped the project root's parent instead of the project root; the author renamed manifest.json or used a different schema.
Related errors
- Invalid command: command must be a non-empty string
- Invalid command: command cannot be empty
- Invalid command: path traversal detected in "${command}"
- Invalid command: null byte detected
- Invalid args: must be an array
AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12).
Data as JSON: /api/errors/d2077ce03360cbef.
Report an issue: GitHub.