{"record":{"id":"d4dc2b7fef65b538","repo":"RocketChat/Rocket.Chat","slug":"no-app-json-file-found-in-the-zip","errorCode":null,"errorMessage":"No app.json file found in the zip","messagePattern":"No app\\.json file found in the zip","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/meteor/client/views/marketplace/lib/getManifestFromZippedApp.ts","lineNumber":22,"sourceCode":"type Uint8ArrayObject = { [fileName: string]: Uint8Array };\ntype AppManifestSchema = { id: string; name: string; permissions: AppPermission[] };\n\nasync function fileToUint8Array(file: File): Promise<Uint8Array> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst fileReader = new FileReader();\n\t\tfileReader.onload = (e): void => resolve(new Uint8Array((e.target as any).result as Uint8Array));\n\t\tfileReader.onerror = (e): void => reject(e);\n\t\tfileReader.readAsArrayBuffer(file);\n\t});\n}\n\nfunction unzipAppBuffer(zippedAppBuffer: Uint8Array): Uint8ArrayObject {\n\treturn unzipSync(zippedAppBuffer);\n}\n\nfunction getAppManifest(unzippedAppBuffer: Uint8ArrayObject): AppManifestSchema {\n\tif (!unzippedAppBuffer['app.json']) {\n\t\tthrow new Error('No app.json file found in the zip');\n\t}\n\n\ttry {\n\t\treturn JSON.parse(strFromU8(unzippedAppBuffer['app.json']));\n\t} catch (e) {\n\t\tthrow new Error(`Failed to parse app.json: ${e instanceof Error ? e.message : String(e)}`);\n\t}\n}\n\nasync function unzipZippedApp(zippedApp: File | Uint8Array): Promise<Uint8ArrayObject> {\n\ttry {\n\t\tif (zippedApp instanceof File) {\n\t\t\tzippedApp = await fileToUint8Array(zippedApp);\n\t\t}\n\n\t\treturn unzipAppBuffer(zippedApp);\n\t} catch (e) {\n\t\tconsole.error(e);","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/client/views/marketplace/lib/getManifestFromZippedApp.ts#L4-L40","documentation":"getAppManifest() in the marketplace app-install helper throws this when the zip buffer unzipped by fflate's unzipSync contains no entry keyed exactly 'app.json' — i.e. the apps-engine package layout is wrong. Every Rocket.Chat app package must have app.json at the root of the zip archive.","triggerScenarios":"Uploading an app zip where app.json lives in a nested folder ('my-app/app.json'), a zip created by zipping the parent directory instead of its contents, a download that produced an HTML error page instead of a zip, or an archive without a manifest at all.","commonSituations":"Developers running zip -r app.zip my-app/ instead of zipping from inside the folder; macOS double-compression (.zip.cpgz); CI packaging scripts changing the root layout; downloading apps from a URL that returned an error page.","solutions":["List the archive contents (unzip -l app.zip) and confirm app.json is at the root.","Rebuild the zip from inside the app folder so entries are top-level: zip -r ../app.zip app.json src/ ... (or use the apps-engine packaging script).","Verify the downloaded file is actually a zip (file app.zip) and not an HTML error payload."],"exampleFix":"# before: my-app.zip\n#   my-app/app.json   (nested → throws)\n\n# after: my-app.zip\n#   app.json          (at zip root)\ncd my-app && zip -r ../my-app.zip app.json src lib","handlingStrategy":"validation","validationCode":"import { unzipSync } from 'fflate';\nconst entries = Object.keys(unzipSync(buffer));\nif (!entries.includes('app.json')) {\n  dispatchToastMessage({ type: 'error', message: 'app.json must be at the zip root' });\n}","typeGuard":"const hasRootManifest = (entries: string[]): boolean => entries.includes('app.json');","tryCatchPattern":null,"preventionTips":["Zip from inside the app folder so app.json is a root entry.","Verify packages with unzip -l before publishing or uploading.","Confirm downloads are real zips (not HTML error pages) before installing."],"tags":["apps-engine","marketplace","zip"],"backgroundTag":"missing-manifest-file","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}